- rewrite of template function handling to improve speed

- bugfix on file dependency when merge_compiled_includes = true
This commit is contained in:
Uwe.Tews
2010-05-25 19:33:55 +00:00
parent eb12b18929
commit 063b8bf150
5 changed files with 175 additions and 125 deletions

View File

@@ -1,5 +1,11 @@
25/05/2010
- rewrite of template function handling to improve speed
- bugfix on file dependency when merge_compiled_includes = true
16/05/2010
- bugfix when passing parameter with numeric name like {foo 1='bar' 2='blar'}
14/05/2010
- bugfix compile new config files if compile_check and force_compile = false
- added variable static classes names to template syntax

View File

@@ -1,28 +1,29 @@
<?php
/**
* Smarty Internal Plugin Compile Function_Call
*
* Compiles the calls of user defined tags defined by {function}
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
* Smarty Internal Plugin Compile Function_Call
*
* Compiles the calls of user defined tags defined by {function}
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Function_Call Class
*/
* Smarty Internal Plugin Compile Function_Call Class
*/
class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase {
/**
* Compiles the calls of user defined tags defined by {function}
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return string compiled code
*/
* Compiles the calls of user defined tags defined by {function}
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return string compiled code
*/
public function compile($args, $compiler)
{
$this->compiler = $compiler;
$this->smarty = $compiler->smarty;
$this->required_attributes = array('name');
$this->optional_attributes = array('_any');
// check and get attributes
@@ -32,32 +33,61 @@ class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase {
// output will be stored in a smarty variable instead of beind displayed
$_assign = $_attr['assign'];
}
// set flag (compiled code of {function} must be included in cache file
if ($this->compiler->nocache || $this->compiler->tag_nocache) {
$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
$_name = trim($_attr['name'], "'\"");
unset($_attr['name'], $_attr['assign']);
// remaining attributes must be assigned as smarty variable
if (!empty($_attr)) {
// create variables
foreach ($_attr as $_key => $_value) {
$_output .= "\$_template->assign('$_key',$_value);\n";
// set flag (compiled code of {function} must be included in cache file
if ($compiler->nocache || $compiler->tag_nocache) {
$_nocache = 'true';
} else {
$_nocache = 'false';
}
$_paramsArray = array();
foreach ($_attr as $_key => $_value) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} else {
$_paramsArray[] = "'$_key'=>$_value";
}
}
if (isset($compiler->template->properties['function'][$_name])) {
foreach ($compiler->template->properties['function'][$_name]['parameter'] as $_key => $_value) {
if (!isset($_attr[$_key])) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} else {
$_paramsArray[] = "'$_key'=>$_value";
}
}
}
} elseif (isset($this->smarty->template->properties['function'][$_name])) {
foreach ($this->smarty->template->properties['function'][$_name]['parameter'] as $_key => $_value) {
if (!isset($_attr[$_key])) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} else {
$_paramsArray[] = "'$_key'=>$_value";
}
}
}
}
$_params = 'array(' . implode(",", $_paramsArray) . ')';
$_hash = str_replace('-','_',$compiler->template->properties['nocache_hash']);
// was there an assign attribute
if (isset($_assign)) {
$_output .= "\$_smarty_tpl->assign({$_assign},\$_template->getRenderedTemplate());\n";
if ($compiler->template->caching) {
$_output = "\$_smarty_tpl->assign({$_assign},Smarty_Internal_Function_Call_Handler::call ('{$_name}',\$_smarty_tpl,{$_params},'{$_hash}',{$_nocache}));?>\n";
} else {
$_output = "\$_smarty_tpl->assign({$_assign},smarty_template_function_{$_name}(\$_smarty_tpl,{$_params}));?>\n";
}
} else {
$_output .= "echo \$_template->getRenderedTemplate();\n";
if ($compiler->template->caching) {
$_output = "<?php Smarty_Internal_Function_Call_Handler::call ('{$_name}',\$_smarty_tpl,{$_params},'{$_hash}',{$_nocache});?>\n";
} else {
$_output = "<?php smarty_template_function_{$_name}(\$_smarty_tpl,{$_params});?>\n";
}
}
$_output .= 'unset($_template);?>';
return $_output;
}
}
?>
?>

View File

@@ -1,24 +1,24 @@
<?php
/**
* Smarty Internal Plugin Compile Function
*
* Compiles the {function} {/function} tags
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
* Smarty Internal Plugin Compile Function
*
* Compiles the {function} {/function} tags
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Function Class
*/
* Smarty Internal Plugin Compile Function Class
*/
class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {function} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return boolean true
*/
* Compiles code for the {function} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return boolean true
*/
public function compile($args, $compiler)
{
$this->compiler = $compiler;
@@ -34,33 +34,39 @@ class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase {
foreach ($_attr as $_key => $_data) {
$compiler->template->properties['function'][$_name]['parameter'][$_key] = $_data;
}
// make function known for recursive calls
$this->compiler->smarty->template_functions[$_name]['compiled'] = '';
if ($compiler->template->caching) {
$output = '';
} else {
$output = "<?php if (!function_exists('smarty_template_function_{$_name}')) {
function smarty_template_function_{$_name}(\$_smarty_tpl,\$params) {
\$saved_tpl_vars = \$_smarty_tpl->tpl_vars;
foreach (\$params as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);}?>";
}
// Init temporay context
$compiler->template->required_plugins = array('compiled' => array(), 'nocache' => array());
$compiler->template->extract_code = true;
$compiler->template->extracted_compiled_code = '';
$compiler->template->extracted_compiled_code = $output;
$compiler->template->has_nocache_code = false;
$compiler->has_code = false;
$compiler->template->properties['function'][$_name]['compiled'] = '';
return true;
}
}
/**
* Smarty Internal Plugin Compile Functionclose Class
*/
* Smarty Internal Plugin Compile Functionclose Class
*/
class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {/function} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return boolean true
*/
* Compiles code for the {/function} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return boolean true
*/
public function compile($args, $compiler)
{
$this->compiler = $compiler;
$this->compiler->has_code = false;
$_attr = $this->_get_attributes($args);
$saved_data = $this->_close_tag(array('function'));
$_name = trim($saved_data[0]['name'], "'\"");
@@ -84,16 +90,24 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
}
$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] = $compiler->template->properties['function'][$_name];
// if caching save template function for possible nocache call
if ($compiler->template->caching) {
$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;
$compiler->smarty->template_functions[$_name] = $compiler->template->properties['function'][$_name];
$compiler->has_code = false;
$output = true;
} else {
$output = $plugins_string . $compiler->template->extracted_compiled_code . "<?php \$_smarty_tpl->tpl_vars = \$saved_tpl_vars;}}?>\n";
}
// 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->has_nocache_code = $compiler->template->has_nocache_code | $saved_data[3];
$compiler->template->required_plugins = $saved_data[4];
return true;
return $output;
}
}

View File

@@ -1,25 +1,25 @@
<?php
/**
* Smarty Internal Plugin Compile Include
*
* Compiles the {include} tag
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
* Smarty Internal Plugin Compile Include
*
* Compiles the {include} tag
*
* @package Smarty
* @subpackage Compiler
* @author Uwe Tews
*/
/**
* Smarty Internal Plugin Compile Include Class
*/
* Smarty Internal Plugin Compile Include Class
*/
class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase {
/**
* Compiles code for the {include} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return string compiled code
*/
* Compiles code for the {include} tag
*
* @param array $args array with attributes from parser
* @param object $compiler compiler object
* @return string compiled code
*/
public function compile($args, $compiler)
{
$this->compiler = $compiler;
@@ -40,14 +40,23 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase {
// needs code for cached page but no cache file
$tpl->caching = 9999;
}
if ($this->compiler->template->mustCompile) {
// make sure whole chain gest compiled
$tpl->mustCompile = true;
}
if ($tpl->resource_object->usesCompiler && $tpl->isExisting()) {
// make sure that template is up to date and merge template properties
// $tpl->renderTemplate(); // 06/05/2010
$compiled_tpl = $tpl->getCompiledTemplate(); // 06/05/2010
// compiled code for {function} tags
$compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $tpl->properties['function']);
// get compiled code
// $compiled_tpl = $tpl->getCompiledTemplate(); // 06/05/2010
$compiled_tpl = $tpl->getCompiledTemplate();
// merge compiled code for {function} tags
$compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $tpl->properties['function']);
// merge filedependency by evaluating header code
preg_match_all("/(<\?php \/\*%%SmartyHeaderCode:{$tpl->properties['nocache_hash']}%%\*\/(.+?)\/\*\/%%SmartyHeaderCode%%\*\/\?>\n)/s", $compiled_tpl, $result);
$saved_has_nocache_code = $compiler->template->has_nocache_code;
$saved_nocache_hash = $compiler->template->properties['nocache_hash'];
$_smarty_tpl = $compiler->template;
eval($result[2][0]);
$compiler->template->properties['nocache_hash'] = $saved_nocache_hash;
$compiler->template->has_nocache_code = $saved_has_nocache_code;
// remove header code
$compiled_tpl = preg_replace("/(<\?php \/\*%%SmartyHeaderCode:{$tpl->properties['nocache_hash']}%%\*\/(.+?)\/\*\/%%SmartyHeaderCode%%\*\/\?>\n)/s", '', $compiled_tpl);
if ($tpl->has_nocache_code) {

View File

@@ -1,47 +1,38 @@
<?php
/**
* Smarty Internal Plugin Function Call Handler
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
* Smarty Internal Plugin Function Call Handler
*
* @package Smarty
* @subpackage PluginsInternal
* @author Uwe Tews
*/
/**
* This class does call function defined with the {function} tag
*/
* 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)
static function call ($_name, $_template, $_params, $_hash, $_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']);
if ($_nocache) {
$_function = "smarty_template_function_{$_name}_nocache";
$_template->smarty->template_functions[$_name]['called_nocache'] = true;
} else {
$this->compiled_template = $smarty->template_functions[$name]['compiled'];
$_function = "smarty_template_function_{$_hash}_{$_name}";
}
// 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};"));
if (!is_callable($_function)) {
$_code = "function {$_function}(\$_smarty_tpl,\$params) {
\$saved_tpl_vars = \$_smarty_tpl->tpl_vars;
foreach (\$params as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);}?>";
if ($_nocache) {
$_code .= preg_replace(array("!<\?php echo \\'/\*%%SmartyNocache:{$_template->smarty->template_functions[$_name]['nocache_hash']}%%\*/|/\*/%%SmartyNocache:{$_template->smarty->template_functions[$_name]['nocache_hash']}%%\*/\\';\?>!",
"!\\\'!"), array('', "'"), $_template->smarty->template_functions[$_name]['compiled']);
} else {
$_code .= preg_replace("/{$_template->smarty->template_functions[$_name]['nocache_hash']}/", $_template->properties['nocache_hash'], $_template->smarty->template_functions[$_name]['compiled']);
}
$_code .= "<?php \$_smarty_tpl->tpl_vars = \$saved_tpl_vars;}";
eval($_code);
}
// set flag if {function} contains nocache code
if ($smarty->template_functions[$name]['has_nocache_code']) {
$this->has_nocache_code = true;
}
$_function($_template, $_params);
}
}
?>
?>