From 457a0486f565b595485635a943e201185a4d63bd Mon Sep 17 00:00:00 2001 From: uwetews Date: Tue, 18 Aug 2015 02:55:53 +0200 Subject: [PATCH] - cache template object of {include} if same template is included several times --- change_log.txt | 5 ++- .../smarty_internal_compile_include.php | 39 ++++++++++++++++--- .../smarty_internal_extension_codeframe.php | 1 + libs/sysplugins/smarty_internal_template.php | 3 +- libs/sysplugins/smarty_template_compiled.php | 13 +++++++ .../smarty_template_resource_base.php | 7 ++++ 6 files changed, 60 insertions(+), 8 deletions(-) diff --git a/change_log.txt b/change_log.txt index 0a82eb75..4ffec59b 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,7 +1,8 @@  ===== 3.1.28-dev===== (xx.xx.2015) xx.xx.2015 - - introduce Smarty::$resource_cache_mode and cache template object of {include} inside loop - - load seldom used Smarty API methods dynamically to reduce memory footprint + - introduce Smarty::$resource_cache_mode and cache template object of {include} inside loop + - load seldom used Smarty API methods dynamically to reduce memory footprint + - cache template object of {include} if same template is included several times 06.08.2015 - avoid possible circular object references caused by parser/lexer objects diff --git a/libs/sysplugins/smarty_internal_compile_include.php b/libs/sysplugins/smarty_internal_compile_include.php index ed427ac4..7f45296a 100644 --- a/libs/sysplugins/smarty_internal_compile_include.php +++ b/libs/sysplugins/smarty_internal_compile_include.php @@ -70,6 +70,14 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase // save possible attributes $include_file = $_attr['file']; + if ($compiler->has_variable_string || + !((substr_count($include_file, '"') == 2 || substr_count($include_file, "'") == 2)) || + substr_count($include_file, '(') != 0 || substr_count($include_file, '$_smarty_tpl->') != 0 + ) { + $variable_template = true; + } else { + $variable_template = false; + } if (isset($_attr['assign'])) { // output will be stored in a smarty variable instead of being displayed @@ -89,7 +97,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase } // - if ($compiler->loopNesting > 0) { + if ($variable_template || $compiler->loopNesting > 0) { $_cache_tpl = 'true'; } else { $_cache_tpl = 'false'; @@ -115,10 +123,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase if ($merge_compiled_includes && $_attr['inline'] !== true) { // variable template name ? - if ($compiler->has_variable_string || - !((substr_count($include_file, '"') == 2 || substr_count($include_file, "'") == 2)) || - substr_count($include_file, '(') != 0 || substr_count($include_file, '$_smarty_tpl->') != 0 - ) { + if ($variable_template) { $merge_compiled_includes = false; if ($compiler->template->caching) { // must use individual cache file @@ -262,6 +267,8 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase } else { $_vars = 'array()'; } + $this->logInclude($compiler, $include_file, $variable_template); + $update_compile_id = $compiler->template->caching && !$compiler->tag_nocache && !$compiler->nocache && $_compile_id != '$_smarty_tpl->compile_id'; if ($has_compiled_template && !$call_nocache) { @@ -306,4 +313,26 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase $_output .= "?>\n"; return $_output; } + + /** + * log include count + * + * @param \Smarty_Internal_SmartyTemplateCompiler $compiler + * @param string $include_file + * @param bool $variable_template + */ + private function logInclude(Smarty_Internal_SmartyTemplateCompiler $compiler, $include_file, $variable_template) + { + if ($variable_template) { + return; + } + list($name, $type) = Smarty_Resource::parseResourceName(trim($include_file, '\'"'), $compiler->template->smarty->default_resource_type); + if (in_array($type, array('eval', 'string'))) { + return; + } + $include_name = $type . ':' . $name; + $compiled = $compiler->parent_compiler->template->compiled; + $compiled->includes[$include_name] = isset($compiled->includes[$include_name]) ? $compiled->includes[$include_name] + + 1 : 1; + } } diff --git a/libs/sysplugins/smarty_internal_extension_codeframe.php b/libs/sysplugins/smarty_internal_extension_codeframe.php index 484ee257..9b12d0c6 100644 --- a/libs/sysplugins/smarty_internal_extension_codeframe.php +++ b/libs/sysplugins/smarty_internal_extension_codeframe.php @@ -34,6 +34,7 @@ class Smarty_Internal_Extension_CodeFrame } if (!$cache) { $properties['file_dependency'] = $_template->compiled->file_dependency; + $properties['includes'] = $_template->compiled->includes; } else { $properties['file_dependency'] = $_template->cached->file_dependency; $properties['cache_lifetime'] = $_template->cache_lifetime; diff --git a/libs/sysplugins/smarty_internal_template.php b/libs/sysplugins/smarty_internal_template.php index 47de4a7a..eaeb9fdc 100644 --- a/libs/sysplugins/smarty_internal_template.php +++ b/libs/sysplugins/smarty_internal_template.php @@ -118,7 +118,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase * @param mixed $_compile_id compile id or null * @param bool $_caching use caching? * @param int $_cache_lifetime cache life-time in seconds - * @param string $_templateId optional from extern + * @param string $_templateId optional from extern * * @throws \SmartyException */ @@ -660,6 +660,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase } else { $this->mustCompile = !$is_valid; $resource = $this->compiled; + $resource->includes = $properties['includes']; } if ($is_valid) { $resource->unifunc = $properties['unifunc']; diff --git a/libs/sysplugins/smarty_template_compiled.php b/libs/sysplugins/smarty_template_compiled.php index 12d2bd8f..29d6d408 100644 --- a/libs/sysplugins/smarty_template_compiled.php +++ b/libs/sysplugins/smarty_template_compiled.php @@ -19,6 +19,7 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base */ public $nocache_hash = null; + /** * create Compiled Object container */ @@ -156,6 +157,18 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base $_template->smarty->compile_check = $compileCheck; } } + if (!$_template->source->isConfig && !isset($_template->smarty->template_objects[$_template->templateId]) && + $_template->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_AUTOMATIC && + $_template->parent instanceof Smarty_Internal_Template && isset($_template->parent->compiled) + ) { + foreach ($_template->parent->compiled->includes as $key => $count) { + $_template->compiled->includes[$key] = isset($_template->compiled->includes[$key]) ? $_template->compiled->includes[$key] + + $count : $count; + } + if (!in_array($_template->source->type, array('eval', 'string')) && $_template->compiled->includes[$_template->source->type . ':' . $_template->source->name] > 1) { + $_template->smarty->template_objects[$_template->templateId] = $_template; + } + } $this->processed = true; } diff --git a/libs/sysplugins/smarty_template_resource_base.php b/libs/sysplugins/smarty_template_resource_base.php index bdcaf8c1..fa5d99ba 100644 --- a/libs/sysplugins/smarty_template_resource_base.php +++ b/libs/sysplugins/smarty_template_resource_base.php @@ -87,6 +87,13 @@ abstract class Smarty_Template_Resource_Base */ public $tpl_function = array(); + /** + * Included subtemplates + * + * @var array + */ + public $includes = array(); + /** * Process resource *