mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-06 19:34:27 +02:00
- optimization of generated code for doublequoted strings containing variables
- rewrite of {function} tag handling - can now be declared in an external subtemplate - can contain nocache sections (nocache_hash handling) - can be called in noccache sections (nocache_hash handling) - new {call..} tag to call template functions with a variable name {call name=$foo} - fixed nocache_hash handling in merged compiled templates
This commit is contained in:
@@ -1,3 +1,12 @@
|
||||
12/31/2009
|
||||
- optimization of generated code for doublequoted strings containing variables
|
||||
- rewrite of {function} tag handling
|
||||
- can now be declared in an external subtemplate
|
||||
- can contain nocache sections (nocache_hash handling)
|
||||
- can be called in noccache sections (nocache_hash handling)
|
||||
- new {call..} tag to call template functions with a variable name {call name=$foo}
|
||||
- fixed nocache_hash handling in merged compiled templates
|
||||
|
||||
12/30/2009
|
||||
- bugfix for plugins defined in the script as smarty_function_foo
|
||||
|
||||
|
@@ -32,32 +32,14 @@ class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase {
|
||||
// output will be stored in a smarty variable instead of beind displayed
|
||||
$_assign = $_attr['assign'];
|
||||
}
|
||||
$_name = trim($_attr['name'], "'");
|
||||
// create template object
|
||||
$_output = "<?php \$_template = new {$compiler->smarty->template_class} ('string:', \$_smarty_tpl->smarty, \$_smarty_tpl);\n";
|
||||
$_output .= "\$_template->properties['nocache_hash'] = \$_smarty_tpl->smarty->template_functions['$_name']['nocache_hash'];\n";
|
||||
// set flag (compiled code of {function} must be included in cache file
|
||||
if ($this->compiler->nocache || $this->compiler->tag_nocache) {
|
||||
$compiler->smarty->template_functions[$_name]['called_nocache'] = true;
|
||||
$compiler->template->properties['function'][$_name]['called_nocache'] = true;
|
||||
}
|
||||
// assign default paramter
|
||||
if (isset($this->smarty->template_functions[$_name]['parameter'])) {
|
||||
// function is already compiled
|
||||
foreach ($this->smarty->template_functions[$_name]['parameter'] as $_key => $_value) {
|
||||
if (!isset($_attr[$_key])) {
|
||||
$_output .= "\$_template->assign('$_key',$_value);\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
if (isset($compiler->template->properties['function'][$_name]['parameter'])) {
|
||||
// for recursive call during function compilation
|
||||
foreach ($compiler->template->properties['function'][$_name]['parameter'] as $_key => $_value) {
|
||||
if (!isset($_attr[$_key])) {
|
||||
$_output .= "\$_template->assign('$_key',$_value);\n";
|
||||
}
|
||||
}
|
||||
$nocache = 'true';
|
||||
} else {
|
||||
$nocache = 'false';
|
||||
}
|
||||
// create template object
|
||||
$_output = "<?php \$_template = new Smarty_Internal_Function_Call_Handler ({$_attr['name']}, \$_smarty_tpl->smarty, \$_smarty_tpl, {$nocache});\n";
|
||||
// delete {include} standard attributes
|
||||
unset($_attr['name'], $_attr['assign']);
|
||||
// remaining attributes must be assigned as smarty variable
|
||||
@@ -67,14 +49,13 @@ class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase {
|
||||
$_output .= "\$_template->assign('$_key',$_value);\n";
|
||||
}
|
||||
}
|
||||
// load compiled function
|
||||
$_output .= "\$_template->compiled_template = \$this->smarty->template_functions['$_name']['compiled'];\n\$_template->mustCompile = false;\n";
|
||||
// was there an assign attribute
|
||||
if (isset($_assign)) {
|
||||
$_output .= "\$_smarty_tpl->assign($_assign,\$_template->getRenderedTemplate()); ?>";
|
||||
$_output .= "\$_smarty_tpl->assign({$_assign},\$_template->getRenderedTemplate());\n";
|
||||
} else {
|
||||
$_output .= "echo \$_template->getRenderedTemplate(); ?>";
|
||||
$_output .= "echo \$_template->getRenderedTemplate();\n";
|
||||
}
|
||||
$_output .= 'unset($_template);?>';
|
||||
return $_output;
|
||||
}
|
||||
}
|
||||
|
@@ -26,7 +26,8 @@ class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase {
|
||||
$this->optional_attributes = array('_any');
|
||||
// check and get attributes
|
||||
$_attr = $this->_get_attributes($args);
|
||||
$save = array($_attr, $compiler->template->extracted_compiled_code, $compiler->template->extract_code, $compiler->template->has_nocache_code);
|
||||
$save = array($_attr, $compiler->template->extracted_compiled_code, $compiler->template->extract_code,
|
||||
$compiler->template->has_nocache_code, $compiler->template->required_plugins);
|
||||
$this->_open_tag('function', $save);
|
||||
$_name = trim($_attr['name'], "'");
|
||||
unset($_attr['name']);
|
||||
@@ -34,7 +35,9 @@ class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase {
|
||||
$compiler->template->properties['function'][$_name]['parameter'][$_key] = $_data;
|
||||
}
|
||||
// make function known for recursive calls
|
||||
$this->compiler->smarty->template_functions[$_name]['compiled'] = '';
|
||||
$this->compiler->smarty->template_functions[$_name]['compiled'] = '';
|
||||
// Init temporay context
|
||||
$compiler->template->required_plugins = array('compiled' => array(), 'cache' => array());
|
||||
$compiler->template->extract_code = true;
|
||||
$compiler->template->extracted_compiled_code = '';
|
||||
$compiler->template->has_code = false;
|
||||
@@ -60,18 +63,35 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
|
||||
$this->compiler->has_code = false;
|
||||
$_attr = $this->_get_attributes($args);
|
||||
$saved_data = $this->_close_tag(array('function'));
|
||||
$_name = trim($saved_data[0]['name'], "'");
|
||||
$compiler->template->properties['function'][$_name]['compiled'] = $compiler->template->extracted_compiled_code;
|
||||
$_name = trim($saved_data[0]['name'], "'");
|
||||
// build plugin include code
|
||||
$plugins_string = '';
|
||||
if (!empty($compiler->template->required_plugins['compiled'])) {
|
||||
$plugins_string = '<?php ';
|
||||
foreach($compiler->template->required_plugins['compiled'] as $plugin_name => $data) {
|
||||
$plugin = 'smarty_' . $data['type'] . '_' . $plugin_name;
|
||||
$plugins_string .= "if (!is_callable('{$plugin}')) include '{$data['file']}';\n";
|
||||
}
|
||||
$plugins_string .= '?>';
|
||||
}
|
||||
if (!empty($compiler->template->required_plugins['cache'])) {
|
||||
$plugins_string .= "<?php echo '/*%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/<?php ";
|
||||
foreach($compiler->template->required_plugins['cache'] as $plugin_name => $data) {
|
||||
$plugin = 'smarty_' . $data['type'] . '_' . $plugin_name;
|
||||
$plugins_string .= "if (!is_callable(\'{$plugin}\')) include \'{$data['file']}\';\n";
|
||||
}
|
||||
$plugins_string .= "?>/*/%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/';?>\n";
|
||||
}
|
||||
$compiler->template->properties['function'][$_name]['compiled'] = $plugins_string . $compiler->template->extracted_compiled_code;
|
||||
$compiler->template->properties['function'][$_name]['nocache_hash'] = $compiler->template->properties['nocache_hash'];
|
||||
$compiler->template->properties['function'][$_name]['has_nocache_code'] = $compiler->template->has_nocache_code;
|
||||
$this->compiler->smarty->template_functions[$_name]['compiled'] = $compiler->template->extracted_compiled_code;
|
||||
$this->compiler->smarty->template_functions[$_name]['parameter'] = $compiler->template->properties['function'][$_name]['parameter'];
|
||||
$this->compiler->smarty->template_functions[$_name]['nocache_hash'] = $compiler->template->properties['nocache_hash'];
|
||||
$this->compiler->smarty->template_functions[$_name]['has_nocache_code'] = $compiler->template->has_nocache_code;
|
||||
// restore old code extraction status
|
||||
// $compiler->template->properties['function'][$_name]['plugins'] = $compiler->template->required_plugins;
|
||||
$this->compiler->smarty->template_functions[$_name] = $compiler->template->properties['function'][$_name];
|
||||
// restore old compiler status
|
||||
$compiler->template->extracted_compiled_code = $saved_data[1];
|
||||
$compiler->template->extract_code = $saved_data[2];
|
||||
$compiler->template->has_nocache_code = $saved_data[3];
|
||||
$compiler->template->required_plugins = $saved_data[4];
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@@ -44,7 +44,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase {
|
||||
// make sure that template is up to date and merge template properties
|
||||
$tpl->renderTemplate();
|
||||
// compiled code for {function} tags
|
||||
$compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $tpl->properties['function']);
|
||||
$compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $tpl->properties['function']);
|
||||
// get compiled code
|
||||
$compiled_tpl = $tpl->getCompiledTemplate();
|
||||
// remove header code
|
||||
@@ -107,7 +107,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase {
|
||||
}
|
||||
}
|
||||
// create template object
|
||||
$_output = "<?php \$_template = new {$compiler->smarty->template_class}($include_file, \$_smarty_tpl->smarty, \$_smarty_tpl, \$_smarty_tpl->cache_id, \$_smarty_tpl->compile_id, $_caching, $_cache_lifetime);";
|
||||
$_output = "<?php \$_template = new {$compiler->smarty->template_class}($include_file, \$_smarty_tpl->smarty, \$_smarty_tpl, \$_smarty_tpl->cache_id, \$_smarty_tpl->compile_id, $_caching, $_cache_lifetime);\n";
|
||||
// delete {include} standard attributes
|
||||
unset($_attr['file'], $_attr['assign'], $_attr['cache_lifetime'], $_attr['nocache'], $_attr['caching'], $_attr['scope'], $_attr['inline']);
|
||||
// remaining attributes must be assigned as smarty variable
|
||||
@@ -126,6 +126,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase {
|
||||
$_output .= "\$_smarty_tpl->assign($_assign,\$_template->getRenderedTemplate());?>";
|
||||
} else {
|
||||
if ($has_compiled_template && !($compiler->template->caching && ($this->compiler->tag_nocache || $this->compiler->nocache))) {
|
||||
$_output .= "\$_template->properties['nocache_hash'] = '{$compiler->template->properties['nocache_hash']}';\n";
|
||||
$_output .= "\$_tpl_stack[] = \$_smarty_tpl; \$_smarty_tpl = \$_template;?>\n";
|
||||
$_output .= $compiled_tpl;
|
||||
$_output .= "<?php \$_smarty_tpl->updateParentVariables($_parent_scope);?>";
|
||||
|
47
libs/sysplugins/smarty_internal_function_call_handler.php
Normal file
47
libs/sysplugins/smarty_internal_function_call_handler.php
Normal file
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
/**
|
||||
* Smarty Internal Plugin Function Call Handler
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage Security
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
/**
|
||||
* This class does call function defined with the {function} tag
|
||||
*/
|
||||
class Smarty_Internal_Function_Call_Handler extends Smarty_Internal_Template {
|
||||
function __construct($name, $smarty, $parent, $nocache)
|
||||
{
|
||||
parent::__construct('string:', $smarty, $parent);
|
||||
if (!isset($this->smarty->template_functions[$name])) {
|
||||
throw new Exception("Call to undefined template function \"{$name}\" in template \"{$parent->template_resource}\"");
|
||||
}
|
||||
$this->called_nocache = $nocache;
|
||||
$this->mustCompile = false;
|
||||
if ($nocache) {
|
||||
$smarty->template_functions[$name]['called_nocache'] = true;
|
||||
$this->properties['function'][$name]['called_nocache'] = true;
|
||||
}
|
||||
$this->properties['nocache_hash'] = $smarty->template_functions[$name]['nocache_hash'];
|
||||
// load compiled function
|
||||
if ($nocache) {
|
||||
// if called in nocache mode convert nocache code to real code
|
||||
$this->compiled_template = preg_replace(array("!(<\?php echo ')?/\*/?%%SmartyNocache:{$this->smarty->template_functions[$name]['nocache_hash']}%%\*/(';\?>)?!", "!\\\'!"), array('', "'"), $smarty->template_functions[$name]['compiled']);
|
||||
} else {
|
||||
$this->compiled_template = $smarty->template_functions[$name]['compiled'];
|
||||
}
|
||||
// assign default paramter
|
||||
if (isset($smarty->template_functions[$name]['parameter'])) {
|
||||
$_smarty_tpl = $this;
|
||||
foreach ($smarty->template_functions[$name]['parameter'] as $_key => $_value) {
|
||||
$this->assign($_key, eval("return {$_value};"));
|
||||
}
|
||||
}
|
||||
// set flag if {function} contains nocache code
|
||||
if ($smarty->template_functions[$name]['has_nocache_code']) {
|
||||
$this->has_nocache_code = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
@@ -484,6 +484,11 @@ class Smarty_Internal_Template extends Smarty_Internal_Data {
|
||||
if ($this->smarty->debugging) {
|
||||
Smarty_Internal_Debug::start_cache($this);
|
||||
}
|
||||
// dummy renderung because of {function} nocache handling
|
||||
$_smarty_tpl = $this;
|
||||
ob_start();
|
||||
eval("?>" . $this->rendered_content);
|
||||
ob_get_clean();
|
||||
// write rendered template
|
||||
if (!$this->cacheFileWritten) {
|
||||
$this->writeCachedContent($this);
|
||||
@@ -495,10 +500,11 @@ class Smarty_Internal_Template extends Smarty_Internal_Data {
|
||||
Smarty_Internal_Debug::end_cache($this);
|
||||
}
|
||||
} else {
|
||||
// var_dump('renderTemplate',$this->has_nocache_code,$this->template_resource, $this->has_nocache_code, $this->properties['nocache_hash'], $this->parent->properties['nocache_hash'], $this->rendered_content);
|
||||
// var_dump('renderTemplate', $this->has_nocache_code, $this->template_resource, $this->properties['nocache_hash'], $this->parent->properties['nocache_hash'], $this->rendered_content);
|
||||
if ($this->has_nocache_code && !empty($this->properties['nocache_hash']) && !empty($this->parent->properties['nocache_hash'])) {
|
||||
// replace nocache_hash
|
||||
$this->rendered_content = preg_replace("/{$this->properties['nocache_hash']}/", $this->parent->properties['nocache_hash'], $this->rendered_content);
|
||||
$this->parent->has_nocache_code = $this->has_nocache_code;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -780,6 +786,7 @@ class Smarty_Internal_Template extends Smarty_Internal_Data {
|
||||
$this->properties['file_dependency'] = array_merge($this->properties['file_dependency'], $properties['file_dependency']);
|
||||
}
|
||||
if (!empty($properties['function'])) {
|
||||
$this->properties['function'] = array_merge($this->properties['function'], $properties['function']);
|
||||
$this->smarty->template_functions = array_merge($this->smarty->template_functions, $properties['function']);
|
||||
}
|
||||
}
|
||||
|
@@ -117,7 +117,7 @@ class Smarty_Internal_TemplateCompilerBase {
|
||||
if (($_output = $this->callTagCompiler($tag, $args)) === false) {
|
||||
if (isset($this->smarty->template_functions[$tag])) {
|
||||
// template defined by {template} tag
|
||||
$args['name'] = $tag;
|
||||
$args['name'] = "'" . $tag . "'";
|
||||
$_output = $this->callTagCompiler('call', $args);
|
||||
}
|
||||
}
|
||||
@@ -287,29 +287,30 @@ class Smarty_Internal_TemplateCompilerBase {
|
||||
foreach((array)$this->smarty->plugins_dir as $_plugin_dir) {
|
||||
$file = rtrim($_plugin_dir, '/\\') . DS . $type . '.' . $plugin_name . '.php';
|
||||
if (file_exists($file)) {
|
||||
require_once($file);
|
||||
// require_once($file);
|
||||
$found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if ($found) {
|
||||
if (is_callable($plugin)) {
|
||||
$this->template->required_plugins_call[$plugin_name][$type] = $plugin;
|
||||
if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
|
||||
$this->template->required_plugins['cache'][$plugin_name]['file'] = $file;
|
||||
$this->template->required_plugins['cache'][$plugin_name]['type'] = $type;
|
||||
} else {
|
||||
$this->template->required_plugins['compiled'][$plugin_name]['file'] = $file;
|
||||
$this->template->required_plugins['compiled'][$plugin_name]['type'] = $type;
|
||||
}
|
||||
if ($type == 'modifier') {
|
||||
$this->template->saved_modifer[$plugin_name] = true;
|
||||
}
|
||||
|
||||
return $plugin;
|
||||
// if (is_callable($plugin)) {
|
||||
$this->template->required_plugins_call[$plugin_name][$type] = $plugin;
|
||||
if ($this->template->caching && ($this->nocache || $this->tag_nocache)) {
|
||||
$this->template->required_plugins['cache'][$plugin_name]['file'] = $file;
|
||||
$this->template->required_plugins['cache'][$plugin_name]['type'] = $type;
|
||||
} else {
|
||||
$this->template->required_plugins['compiled'][$plugin_name]['file'] = $file;
|
||||
$this->template->required_plugins['compiled'][$plugin_name]['type'] = $type;
|
||||
}
|
||||
if ($type == 'modifier') {
|
||||
$this->template->saved_modifer[$plugin_name] = true;
|
||||
}
|
||||
|
||||
return $plugin;
|
||||
/* } else {
|
||||
throw new Exception("Plugin {$type} \"{$plugin_name}\" not callable");
|
||||
}
|
||||
*/
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
@@ -1826,9 +1826,9 @@ static public $yy_action = array(
|
||||
174 => 174,
|
||||
175 => 175,
|
||||
179 => 179,
|
||||
182 => 179,
|
||||
180 => 180,
|
||||
180 => 179,
|
||||
181 => 181,
|
||||
182 => 182,
|
||||
183 => 183,
|
||||
184 => 184,
|
||||
);
|
||||
@@ -2273,20 +2273,25 @@ static public $yy_action = array(
|
||||
function yy_r175(){ $this->_retvalue = '\''.$this->yystack[$this->yyidx + -2]->minor.'\'=>'.$this->yystack[$this->yyidx + 0]->minor; }
|
||||
#line 2269 "smarty_internal_templateparser.php"
|
||||
#line 515 "smarty_internal_templateparser.y"
|
||||
function yy_r179(){$this->_retvalue = '".'.$this->yystack[$this->yyidx + -1]->minor.'."'; $this->compiler->has_variable_string = true; }
|
||||
function yy_r179(){$this->_retvalue = '{'.$this->yystack[$this->yyidx + -1]->minor.'}'; $this->compiler->has_variable_string = true; }
|
||||
#line 2272 "smarty_internal_templateparser.php"
|
||||
#line 516 "smarty_internal_templateparser.y"
|
||||
function yy_r180(){$this->_retvalue = '".('.$this->yystack[$this->yyidx + -1]->minor.')."'; $this->compiler->has_variable_string = true; }
|
||||
#line 2275 "smarty_internal_templateparser.php"
|
||||
#line 517 "smarty_internal_templateparser.y"
|
||||
function yy_r181(){$this->_retvalue = '".'.'$_smarty_tpl->getVariable(\''. substr($this->yystack[$this->yyidx + 0]->minor,1) .'\')->value'.'."'; $this->compiler->tag_nocache=$this->compiler->tag_nocache|$this->template->getVariable(trim($this->yystack[$this->yyidx + 0]->minor,"'"), null, true, false)->nocache; $this->compiler->has_variable_string = true; }
|
||||
#line 2278 "smarty_internal_templateparser.php"
|
||||
#line 519 "smarty_internal_templateparser.y"
|
||||
function yy_r181(){$this->_retvalue = '{$_smarty_tpl->getVariable(\''. substr($this->yystack[$this->yyidx + 0]->minor,1) .'\')->value}'; $this->compiler->tag_nocache=$this->compiler->tag_nocache|$this->template->getVariable(trim($this->yystack[$this->yyidx + 0]->minor,"'"), null, true, false)->nocache; $this->compiler->has_variable_string = true; }
|
||||
#line 2275 "smarty_internal_templateparser.php"
|
||||
#line 518 "smarty_internal_templateparser.y"
|
||||
function yy_r182(){if (substr($this->yystack[$this->yyidx + -1]->minor,0,1) == '\'') {
|
||||
$this->_retvalue = '".'.$this->yystack[$this->yyidx + -1]->minor.'."'; $this->compiler->has_variable_string = true;
|
||||
} else {
|
||||
$this->_retvalue = '{'.$this->yystack[$this->yyidx + -1]->minor.'}'; $this->compiler->has_variable_string = true;
|
||||
}
|
||||
}
|
||||
#line 2283 "smarty_internal_templateparser.php"
|
||||
#line 524 "smarty_internal_templateparser.y"
|
||||
function yy_r183(){ $this->_retvalue = '".('.$this->yystack[$this->yyidx + -1]->minor.')."'; $this->compiler->has_variable_string = true; }
|
||||
#line 2281 "smarty_internal_templateparser.php"
|
||||
#line 520 "smarty_internal_templateparser.y"
|
||||
function yy_r184(){ $this->prefix_number++; $this->compiler->prefix_code[] = '<?php ob_start();?>'.$this->yystack[$this->yyidx + 0]->minor.'<?php $_tmp'.$this->prefix_number.'=ob_get_clean();?>'; $this->_retvalue = '".$_tmp'.$this->prefix_number.'."'; $this->compiler->has_variable_string = true; }
|
||||
#line 2284 "smarty_internal_templateparser.php"
|
||||
#line 2286 "smarty_internal_templateparser.php"
|
||||
#line 525 "smarty_internal_templateparser.y"
|
||||
function yy_r184(){ $this->prefix_number++; $this->compiler->prefix_code[] = '<?php ob_start();?>'.$this->yystack[$this->yyidx + 0]->minor.'<?php $_tmp'.$this->prefix_number.'=ob_get_clean();?>'; $this->_retvalue = '{$_tmp'.$this->prefix_number.'}'; $this->compiler->has_variable_string = true; }
|
||||
#line 2289 "smarty_internal_templateparser.php"
|
||||
|
||||
private $_retvalue;
|
||||
|
||||
@@ -2348,7 +2353,7 @@ static public $yy_action = array(
|
||||
$this->internalError = true;
|
||||
$this->yymajor = $yymajor;
|
||||
$this->compiler->trigger_template_error();
|
||||
#line 2347 "smarty_internal_templateparser.php"
|
||||
#line 2352 "smarty_internal_templateparser.php"
|
||||
}
|
||||
|
||||
function yy_accept()
|
||||
@@ -2365,7 +2370,7 @@ static public $yy_action = array(
|
||||
$this->internalError = false;
|
||||
$this->retvalue = $this->_retvalue;
|
||||
//echo $this->retvalue."\n\n";
|
||||
#line 2365 "smarty_internal_templateparser.php"
|
||||
#line 2370 "smarty_internal_templateparser.php"
|
||||
}
|
||||
|
||||
function doParse($yymajor, $yytokenvalue)
|
||||
|
Reference in New Issue
Block a user