- 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 16/05/2010
- bugfix when passing parameter with numeric name like {foo 1='bar' 2='blar'} - bugfix when passing parameter with numeric name like {foo 1='bar' 2='blar'}
14/05/2010 14/05/2010
- bugfix compile new config files if compile_check and force_compile = false - bugfix compile new config files if compile_check and force_compile = false
- added variable static classes names to template syntax - added variable static classes names to template syntax

View File

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

View File

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

View File

@@ -1,25 +1,25 @@
<?php <?php
/** /**
* Smarty Internal Plugin Compile Include * Smarty Internal Plugin Compile Include
* *
* Compiles the {include} tag * Compiles the {include} tag
* *
* @package Smarty * @package Smarty
* @subpackage Compiler * @subpackage Compiler
* @author Uwe Tews * @author Uwe Tews
*/ */
/** /**
* Smarty Internal Plugin Compile Include Class * Smarty Internal Plugin Compile Include Class
*/ */
class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase { class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase {
/** /**
* Compiles code for the {include} tag * Compiles code for the {include} tag
* *
* @param array $args array with attributes from parser * @param array $args array with attributes from parser
* @param object $compiler compiler object * @param object $compiler compiler object
* @return string compiled code * @return string compiled code
*/ */
public function compile($args, $compiler) public function compile($args, $compiler)
{ {
$this->compiler = $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 // needs code for cached page but no cache file
$tpl->caching = 9999; $tpl->caching = 9999;
} }
if ($this->compiler->template->mustCompile) {
// make sure whole chain gest compiled
$tpl->mustCompile = true;
}
if ($tpl->resource_object->usesCompiler && $tpl->isExisting()) { 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 // 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 // remove header code
$compiled_tpl = preg_replace("/(<\?php \/\*%%SmartyHeaderCode:{$tpl->properties['nocache_hash']}%%\*\/(.+?)\/\*\/%%SmartyHeaderCode%%\*\/\?>\n)/s", '', $compiled_tpl); $compiled_tpl = preg_replace("/(<\?php \/\*%%SmartyHeaderCode:{$tpl->properties['nocache_hash']}%%\*\/(.+?)\/\*\/%%SmartyHeaderCode%%\*\/\?>\n)/s", '', $compiled_tpl);
if ($tpl->has_nocache_code) { if ($tpl->has_nocache_code) {

View File

@@ -1,47 +1,38 @@
<?php <?php
/** /**
* Smarty Internal Plugin Function Call Handler * Smarty Internal Plugin Function Call Handler
* *
* @package Smarty * @package Smarty
* @subpackage PluginsInternal * @subpackage PluginsInternal
* @author Uwe Tews * @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 { 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 ($_nocache) {
if (!isset($this->smarty->template_functions[$name])) { $_function = "smarty_template_function_{$_name}_nocache";
throw new Exception("Call to undefined template function \"{$name}\" in template \"{$parent->template_resource}\""); $_template->smarty->template_functions[$_name]['called_nocache'] = true;
}
$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 { } else {
$this->compiled_template = $smarty->template_functions[$name]['compiled']; $_function = "smarty_template_function_{$_hash}_{$_name}";
} }
// assign default paramter if (!is_callable($_function)) {
if (isset($smarty->template_functions[$name]['parameter'])) { $_code = "function {$_function}(\$_smarty_tpl,\$params) {
$_smarty_tpl = $this; \$saved_tpl_vars = \$_smarty_tpl->tpl_vars;
foreach ($smarty->template_functions[$name]['parameter'] as $_key => $_value) { foreach (\$params as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);}?>";
$this->assign($_key, eval("return {$_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 $_function($_template, $_params);
if ($smarty->template_functions[$name]['has_nocache_code']) {
$this->has_nocache_code = true;
}
} }
} }
?> ?>