From 063b8bf1508bed74f5d0c6f2373b122c827157f9 Mon Sep 17 00:00:00 2001 From: "Uwe.Tews" Date: Tue, 25 May 2010 19:33:55 +0000 Subject: [PATCH] - rewrite of template function handling to improve speed - bugfix on file dependency when merge_compiled_includes = true --- change_log.txt | 6 ++ .../smarty_internal_compile_call.php | 98 ++++++++++++------- .../smarty_internal_compile_function.php | 82 +++++++++------- .../smarty_internal_compile_include.php | 53 +++++----- .../smarty_internal_function_call_handler.php | 61 +++++------- 5 files changed, 175 insertions(+), 125 deletions(-) diff --git a/change_log.txt b/change_log.txt index a7dd1f84..e13c57d1 100644 --- a/change_log.txt +++ b/change_log.txt @@ -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 diff --git a/libs/sysplugins/smarty_internal_compile_call.php b/libs/sysplugins/smarty_internal_compile_call.php index 6fd8aa89..009ccc4b 100644 --- a/libs/sysplugins/smarty_internal_compile_call.php +++ b/libs/sysplugins/smarty_internal_compile_call.php @@ -1,28 +1,29 @@ 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 = "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 = "\n"; + } else { + $_output = "\n"; + } } - $_output .= 'unset($_template);?>'; return $_output; } } -?> +?> \ No newline at end of file diff --git a/libs/sysplugins/smarty_internal_compile_function.php b/libs/sysplugins/smarty_internal_compile_function.php index 61090f16..07a8f763 100644 --- a/libs/sysplugins/smarty_internal_compile_function.php +++ b/libs/sysplugins/smarty_internal_compile_function.php @@ -1,24 +1,24 @@ 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 = "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 . "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; } } diff --git a/libs/sysplugins/smarty_internal_compile_include.php b/libs/sysplugins/smarty_internal_compile_include.php index 266e80a1..f69d48c0 100644 --- a/libs/sysplugins/smarty_internal_compile_include.php +++ b/libs/sysplugins/smarty_internal_compile_include.php @@ -1,25 +1,25 @@ 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) { diff --git a/libs/sysplugins/smarty_internal_function_call_handler.php b/libs/sysplugins/smarty_internal_function_call_handler.php index c9b2948d..48bee427 100644 --- a/libs/sysplugins/smarty_internal_function_call_handler.php +++ b/libs/sysplugins/smarty_internal_function_call_handler.php @@ -1,47 +1,38 @@ 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 .= "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); } } -?> +?> \ No newline at end of file