From 336c07c23fb4b55dbacabb289ea4c286652389c9 Mon Sep 17 00:00:00 2001 From: Uwe Tews Date: Wed, 28 Mar 2018 07:15:29 +0200 Subject: [PATCH] - bugfix plugins may not be loaded if {function} or {block} tags are executed in nocache mode https://github.com/smarty-php/smarty/issues/371 --- change_log.txt | 4 + libs/Smarty.class.php | 2 +- .../smarty_internal_compile_block.php | 14 +- .../smarty_internal_compile_function.php | 23 ++- ...arty_internal_compile_private_modifier.php | 4 +- .../smarty_internal_runtime_codeframe.php | 32 +---- .../smarty_internal_runtime_tplfunction.php | 6 +- .../smarty_internal_runtime_updatecache.php | 16 ++- libs/sysplugins/smarty_internal_template.php | 44 ++++-- .../smarty_internal_templatecompilerbase.php | 134 ++++++++++++++---- .../smarty_template_resource_base.php | 7 - 11 files changed, 175 insertions(+), 111 deletions(-) diff --git a/change_log.txt b/change_log.txt index 3d94f2bd..f92af840 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,4 +1,8 @@ ===== 3.1.32 - dev === +26.03.2018 + - bugfix plugins may not be loaded if {function} or {block} tags are executed in nocache mode + https://github.com/smarty-php/smarty/issues/371 + 26.03.2018 - new feature {parent} = {$smarty.block.parent} {child} = {$smarty.block.child} diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index 97c679a0..d9e96703 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -112,7 +112,7 @@ class Smarty extends Smarty_Internal_TemplateBase /** * smarty version */ - const SMARTY_VERSION = '3.1.32-dev-44'; + const SMARTY_VERSION = '3.1.32-dev-45'; /** * define variable scopes */ diff --git a/libs/sysplugins/smarty_internal_compile_block.php b/libs/sysplugins/smarty_internal_compile_block.php index fa0aa45b..88d6f37e 100644 --- a/libs/sysplugins/smarty_internal_compile_block.php +++ b/libs/sysplugins/smarty_internal_compile_block.php @@ -77,6 +77,7 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_Compile_Shared_Inher array($_attr, $compiler->nocache, $compiler->parser->current_buffer, $compiler->template->compiled->has_nocache_code, $compiler->template->caching)); + $compiler->saveRequiredPlugins(true); $compiler->nocache = $compiler->nocache | $compiler->tag_nocache; $compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template(); $compiler->template->compiled->has_nocache_code = false; @@ -126,7 +127,8 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_Compile_Shared_ $output .= "public \${$property} = " . var_export($value,true) .";\n"; } $output .= "public function callBlock(Smarty_Internal_Template \$_smarty_tpl) {\n"; - //$output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n"; + $output .= $compiler->compileRequiredPlugins(); + $compiler->restoreRequiredPlugins(); if ($compiler->template->compiled->has_nocache_code) { $output .= "\$_smarty_tpl->cached->hashes['{$compiler->template->compiled->nocache_hash}'] = true;\n"; } @@ -151,16 +153,6 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_Compile_Shared_ $output)); $compiler->blockOrFunctionCode .= $compiler->parser->current_buffer->to_smarty_php($compiler->parser); $compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template(); - // nocache plugins must be copied - if (!empty($compiler->template->compiled->required_plugins[ 'nocache' ])) { - foreach ($compiler->template->compiled->required_plugins[ 'nocache' ] as $plugin => $tmp) { - foreach ($tmp as $type => $data) { - $compiler->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin ][ $type ] = - $data; - } - } - } - // restore old status $compiler->template->compiled->has_nocache_code = $_has_nocache_code; $compiler->tag_nocache = $compiler->nocache; diff --git a/libs/sysplugins/smarty_internal_compile_function.php b/libs/sysplugins/smarty_internal_compile_function.php index 9acaafe1..909b767c 100644 --- a/libs/sysplugins/smarty_internal_compile_function.php +++ b/libs/sysplugins/smarty_internal_compile_function.php @@ -67,6 +67,7 @@ class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase // Init temporary context $compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template(); $compiler->template->compiled->has_nocache_code = false; + $compiler->saveRequiredPlugins(true); return true; } } @@ -134,13 +135,14 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase $output .= "if (!function_exists('{$_funcNameCaching}')) {\n"; $output .= "function {$_funcNameCaching} (Smarty_Internal_Template \$_smarty_tpl,\$params) {\n"; $output .= "ob_start();\n"; + $output .= $compiler->compileRequiredPlugins(); $output .= "\$_smarty_tpl->compiled->has_nocache_code = true;\n"; $output .= $_paramsCode; - $output .= "foreach (\$params as \$key => \$value) {\n\$_smarty_tpl->tpl_vars[\$key] = new Smarty_Variable(\$value, \$_smarty_tpl->isRenderingCache);\n}"; + $output .= "foreach (\$params as \$key => \$value) {\n\$_smarty_tpl->tpl_vars[\$key] = new Smarty_Variable(\$value, \$_smarty_tpl->isRenderingCache);\n}\n"; $output .= "\$params = var_export(\$params, true);\n"; $output .= "echo \"/*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/smarty->ext->_tplFunction->saveTemplateVariables(\\\$_smarty_tpl, '{$_name}');\nforeach (\$params as \\\$key => \\\$value) {\n\\\$_smarty_tpl->tpl_vars[\\\$key] = new Smarty_Variable(\\\$value, \\\$_smarty_tpl->isRenderingCache);\n}\n?>"; - $output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n\";?>"; + $output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\";?>"; $compiler->parser->current_buffer->append_subtree($compiler->parser, new Smarty_Internal_ParseTree_Tag($compiler->parser, $output)); @@ -166,7 +168,9 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase $output .= "if (!function_exists('{$_funcName}')) {\n"; $output .= "function {$_funcName}(Smarty_Internal_Template \$_smarty_tpl,\$params) {\n"; $output .= $_paramsCode; - $output .= "foreach (\$params as \$key => \$value) {\n\$_smarty_tpl->tpl_vars[\$key] = new Smarty_Variable(\$value, \$_smarty_tpl->isRenderingCache);\n}?>"; + $output .= "foreach (\$params as \$key => \$value) {\n\$_smarty_tpl->tpl_vars[\$key] = new Smarty_Variable(\$value, \$_smarty_tpl->isRenderingCache);\n}\n"; + $output .= $compiler->compileCheckPlugins(array_merge($compiler->required_plugins[ 'compiled' ], $compiler->required_plugins[ 'nocache' ])); + $output .= "?>\n"; $compiler->parser->current_buffer->append_subtree($compiler->parser, new Smarty_Internal_ParseTree_Tag($compiler->parser, $output)); @@ -178,19 +182,10 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase new Smarty_Internal_ParseTree_Tag($compiler->parser, $output)); $compiler->parent_compiler->blockOrFunctionCode .= $compiler->parser->current_buffer->to_smarty_php($compiler->parser); - // nocache plugins must be copied - if (!empty($compiler->template->compiled->required_plugins[ 'nocache' ])) { - foreach ($compiler->template->compiled->required_plugins[ 'nocache' ] as $plugin => $tmp) { - foreach ($tmp as $type => $data) { - $compiler->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin ][ $type ] = - $data; - } - } - } - // restore old buffer - + // restore old buffer $compiler->parser->current_buffer = $saved_data[ 1 ]; // restore old status + $compiler->restoreRequiredPlugins(); $compiler->template->compiled->has_nocache_code = $saved_data[ 2 ]; $compiler->template->caching = $saved_data[ 3 ]; return true; diff --git a/libs/sysplugins/smarty_internal_compile_private_modifier.php b/libs/sysplugins/smarty_internal_compile_private_modifier.php index ad442a3f..e83b7a24 100644 --- a/libs/sysplugins/smarty_internal_compile_private_modifier.php +++ b/libs/sysplugins/smarty_internal_compile_private_modifier.php @@ -130,8 +130,8 @@ class Smarty_Internal_Compile_Private_Modifier extends Smarty_Internal_CompileBa } } } - if (isset($compiler->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $modifier ][ Smarty::PLUGIN_MODIFIER ][ 'file' ]) || - isset($compiler->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $modifier ][ Smarty::PLUGIN_MODIFIER ][ 'file' ]) + if (isset($compiler->required_plugins[ 'nocache' ][ $modifier ][ Smarty::PLUGIN_MODIFIER ][ 'file' ]) || + isset($compiler->required_plugins[ 'compiled' ][ $modifier ][ Smarty::PLUGIN_MODIFIER ][ 'file' ]) ) { // was a plugin $compiler->known_modifier_type[ $modifier ] = 4; diff --git a/libs/sysplugins/smarty_internal_runtime_codeframe.php b/libs/sysplugins/smarty_internal_runtime_codeframe.php index db303e0a..f792496f 100644 --- a/libs/sysplugins/smarty_internal_runtime_codeframe.php +++ b/libs/sysplugins/smarty_internal_runtime_codeframe.php @@ -58,35 +58,9 @@ class Smarty_Internal_Runtime_CodeFrame var_export($_template->smarty->ext->_tplFunction->getTplFunction($_template), true) . ");\n"; } - // include code for plugins - if (!$cache) { - if (!empty($_template->compiled->required_plugins[ 'compiled' ])) { - foreach ($_template->compiled->required_plugins[ 'compiled' ] as $tmp) { - foreach ($tmp as $data) { - $file = addslashes($data[ 'file' ]); - if (is_array($data[ 'function' ])) { - $output .= "if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) require_once '{$file}';\n"; - } else { - $output .= "if (!is_callable('{$data['function']}')) require_once '{$file}';\n"; - } - } - } - } - if ($_template->caching && !empty($_template->compiled->required_plugins[ 'nocache' ])) { - $_template->compiled->has_nocache_code = true; - $output .= "echo '/*%%SmartyNocache:{$_template->compiled->nocache_hash}%%*/smarty; "; - foreach ($_template->compiled->required_plugins[ 'nocache' ] as $tmp) { - foreach ($tmp as $data) { - $file = addslashes($data[ 'file' ]); - if (is_array($data[ 'function' ])) { - $output .= addslashes("if (!is_callable(array('{$data['function'][0]}','{$data['function'][1]}'))) require_once '{$file}';\n"); - } else { - $output .= addslashes("if (!is_callable('{$data['function']}')) require_once '{$file}';\n"); - } - } - } - $output .= "?>/*/%%SmartyNocache:{$_template->compiled->nocache_hash}%%*/';\n"; - } + // include code for required plugins + if (!$cache && isset($compiler)) { + $output .= $compiler->compileRequiredPlugins(); } $output .= "?>"; $output .= $content; diff --git a/libs/sysplugins/smarty_internal_runtime_tplfunction.php b/libs/sysplugins/smarty_internal_runtime_tplfunction.php index f6b36f2a..b86563cb 100644 --- a/libs/sysplugins/smarty_internal_runtime_tplfunction.php +++ b/libs/sysplugins/smarty_internal_runtime_tplfunction.php @@ -120,15 +120,13 @@ class Smarty_Internal_Runtime_TplFunction } // add template function code to cache file if (isset($tplPtr->cached)) { - /* @var Smarty_Template_Cached $cache */ - $cache = $tplPtr->cached; - $content = $cache->read($tplPtr); + $content = $tplPtr->cached->read($tplPtr); if ($content) { // check if we must update file dependency if (!preg_match("/'{$funcParam['uid']}'(.*?)'nocache_hash'/", $content, $match2)) { $content = preg_replace("/('file_dependency'(.*?)\()/", "\\1{$match1[0]}", $content); } - $tplPtr->smarty->ext->_updateCache->write($cache, $tplPtr, + $tplPtr->smarty->ext->_updateCache->write($tplPtr, preg_replace('/\s*\?>\s*$/', "\n", $content) . "\n" . preg_replace(array('/^\s*<\?php\s+/', '/\s*\?>\s*$/',), "\n", diff --git a/libs/sysplugins/smarty_internal_runtime_updatecache.php b/libs/sysplugins/smarty_internal_runtime_updatecache.php index a3cd21dd..bb3e4e13 100644 --- a/libs/sysplugins/smarty_internal_runtime_updatecache.php +++ b/libs/sysplugins/smarty_internal_runtime_updatecache.php @@ -115,41 +115,43 @@ class Smarty_Internal_Runtime_UpdateCache $content = $_template->smarty->ext->_filterHandler->runFilter('output', $content, $_template); } // write cache file content - $this->writeCachedContent($cached, $_template, $content); + $this->writeCachedContent($_template, $content); } /** * Writes the content to cache resource * - * @param \Smarty_Template_Cached $cached * @param Smarty_Internal_Template $_template * @param string $content * * @return bool */ - public function writeCachedContent(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template, $content) + public function writeCachedContent(Smarty_Internal_Template $_template, $content) { if ($_template->source->handler->recompiled || !$_template->caching ) { // don't write cache file return false; } + if (!isset($_template->cached)) { + $_template->loadCached(); + } $content = $_template->smarty->ext->_codeFrame->create($_template, $content, '', true); - return $this->write($cached, $_template, $content); + return $this->write($_template, $content); } /** * Write this cache object to handler * - * @param \Smarty_Template_Cached $cached * @param Smarty_Internal_Template $_template template object * @param string $content content to cache * * @return bool success */ - public function write(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template, $content) + public function write(Smarty_Internal_Template $_template, $content) { if (!$_template->source->handler->recompiled) { + $cached = $_template->cached; if ($cached->handler->writeCachedContent($_template, $content)) { $cached->content = null; $cached->timestamp = time(); @@ -160,6 +162,7 @@ class Smarty_Internal_Runtime_UpdateCache if ($_template->smarty->cache_locking) { $cached->handler->releaseLock($_template->smarty, $cached); } + return true; } $cached->content = null; @@ -168,6 +171,7 @@ class Smarty_Internal_Runtime_UpdateCache $cached->valid = false; $cached->processed = false; } + return false; } } \ No newline at end of file diff --git a/libs/sysplugins/smarty_internal_template.php b/libs/sysplugins/smarty_internal_template.php index ae321725..21f60f99 100644 --- a/libs/sysplugins/smarty_internal_template.php +++ b/libs/sysplugins/smarty_internal_template.php @@ -234,15 +234,6 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase $this->smarty->_debug->display_debug($this, true); } } - if ($this->_isSubTpl()) { - foreach ($this->compiled->required_plugins as $code => $tmp1) { - foreach ($tmp1 as $name => $tmp) { - foreach ($tmp as $type => $data) { - $this->parent->compiled->required_plugins[ $code ][ $name ][ $type ] = $data; - } - } - } - } if (!$no_output_filter && (!$this->caching || $this->cached->has_nocache_code || $this->source->handler->recompiled) && (isset($this->smarty->autoload_filters[ 'output' ]) || @@ -428,6 +419,39 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase } } + /** + * Check if plugins are callable require file otherwise + * + * @param array $plugins required plugins + * + * @throws \SmartyException + */ + public function _checkPlugins($plugins) { + static $checked = array(); + foreach($plugins as $plugin) { + $name = join('::', (array)$plugin[ 'function' ]); + if (!isset($checked[$name])) { + if (!is_callable($plugin['function'])) { + if (is_file($plugin['file'])) { + require_once $plugin['file']; + if (is_callable($plugin['function'])) { + $checked[ $name ] = true; + } + } + } else { + $checked[ $name ] = true; + } + } + if (!isset($checked[ $name ])) { + if (false !== $this->smarty->loadPlugin($name)) { + $checked[ $name ] = true; + } else { + throw new SmartyException("Plugin '{$name}' not callable"); + } + } + } + } + /** * This function is executed automatically when a compiled or cached template file is included * - Decode saved properties from compiled template and cache files @@ -523,7 +547,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase */ public function writeCachedContent($content) { - return $this->smarty->ext->_updateCache->writeCachedContent($this->cached, $this, $content); + return $this->smarty->ext->_updateCache->writeCachedContent($this, $content); } /** diff --git a/libs/sysplugins/smarty_internal_templatecompilerbase.php b/libs/sysplugins/smarty_internal_templatecompilerbase.php index d4b0fab4..0d7284a0 100644 --- a/libs/sysplugins/smarty_internal_templatecompilerbase.php +++ b/libs/sysplugins/smarty_internal_templatecompilerbase.php @@ -57,6 +57,14 @@ abstract class Smarty_Internal_TemplateCompilerBase * @var bool */ public $suppressNocacheProcessing = false; + + /** + * caching enabled (copied from template object) + * + * @var int + */ + public $caching = 0; + /** * tag stack * @@ -69,6 +77,18 @@ abstract class Smarty_Internal_TemplateCompilerBase * @var array */ public $_tag_stack_count = array(); + /** + * Plugins used by template + * + * @var array + */ + public $required_plugins = array('compiled' => array(), 'nocache' => array()); + /** + * Required plugins stack + * + * @var array + */ + public $required_plugins_stack = array(); /** * current template * @@ -374,6 +394,7 @@ abstract class Smarty_Internal_TemplateCompilerBase } else { $this->nocache_hash = $template->compiled->nocache_hash; } + $this->caching = $template->caching; // flag for nocache sections $this->nocache = $nocache; $this->tag_nocache = false; @@ -711,25 +732,25 @@ abstract class Smarty_Internal_TemplateCompilerBase public function getPlugin($plugin_name, $plugin_type) { $function = null; - if ($this->template->caching && ($this->nocache || $this->tag_nocache)) { - if (isset($this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ])) { + if ($this->caching && ($this->nocache || $this->tag_nocache)) { + if (isset($this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ])) { $function = - $this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ]; - } else if (isset($this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ])) { - $this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ] = - $this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ]; + $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ]; + } else if (isset($this->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ])) { + $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ] = + $this->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ]; $function = - $this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ]; + $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ]; } } else { - if (isset($this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ])) { + if (isset($this->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ])) { $function = - $this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ]; - } else if (isset($this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ])) { - $this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ] = - $this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ]; + $this->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ]; + } else if (isset($this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ])) { + $this->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ] = + $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ]; $function = - $this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ]; + $this->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ]; } } if (isset($function)) { @@ -742,15 +763,15 @@ abstract class Smarty_Internal_TemplateCompilerBase $function = 'smarty_' . $plugin_type . '_' . $plugin_name; $file = $this->smarty->loadPlugin($function, false); if (is_string($file)) { - if ($this->template->caching && ($this->nocache || $this->tag_nocache)) { - $this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'file' ] = + if ($this->caching && ($this->nocache || $this->tag_nocache)) { + $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'file' ] = $file; - $this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ] = + $this->required_plugins[ 'nocache' ][ $plugin_name ][ $plugin_type ][ 'function' ] = $function; } else { - $this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'file' ] = + $this->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'file' ] = $file; - $this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ] = + $this->required_plugins[ 'compiled' ][ $plugin_name ][ $plugin_type ][ 'function' ] = $function; } if ($plugin_type === 'modifier') { @@ -790,15 +811,15 @@ abstract class Smarty_Internal_TemplateCompilerBase $this->tag_nocache = $this->tag_nocache || !$cacheable; if ($script !== null) { if (is_file($script)) { - if ($this->template->caching && ($this->nocache || $this->tag_nocache)) { - $this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $tag ][ $plugin_type ][ 'file' ] = + if ($this->caching && ($this->nocache || $this->tag_nocache)) { + $this->required_plugins[ 'nocache' ][ $tag ][ $plugin_type ][ 'file' ] = $script; - $this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $tag ][ $plugin_type ][ 'function' ] = + $this->required_plugins[ 'nocache' ][ $tag ][ $plugin_type ][ 'function' ] = $callback; } else { - $this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $tag ][ $plugin_type ][ 'file' ] = + $this->required_plugins[ 'compiled' ][ $tag ][ $plugin_type ][ 'file' ] = $script; - $this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $tag ][ $plugin_type ][ 'function' ] = + $this->required_plugins[ 'compiled' ][ $tag ][ $plugin_type ][ 'function' ] = $callback; } require_once $script; @@ -853,7 +874,7 @@ abstract class Smarty_Internal_TemplateCompilerBase // If the template is not evaluated and we have a nocache section and or a nocache tag if ($is_code && !empty($content)) { // generate replacement code - if ((!($this->template->source->handler->recompiled) || $this->forceNocache) && $this->template->caching && + if ((!($this->template->source->handler->recompiled) || $this->forceNocache) && $this->caching && !$this->suppressNocacheProcessing && ($this->nocache || $this->tag_nocache) ) { $this->template->compiled->has_nocache_code = true; @@ -862,9 +883,9 @@ abstract class Smarty_Internal_TemplateCompilerBase $_output = "nocache_hash}%%*/{$_output}/*/%%SmartyNocache:{$this->nocache_hash}%%*/';?>\n"; // make sure we include modifier plugins for nocache code foreach ($this->modifier_plugins as $plugin_name => $dummy) { - if (isset($this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ 'modifier' ])) { - $this->parent_compiler->template->compiled->required_plugins[ 'nocache' ][ $plugin_name ][ 'modifier' ] = - $this->parent_compiler->template->compiled->required_plugins[ 'compiled' ][ $plugin_name ][ 'modifier' ]; + if (isset($this->required_plugins[ 'compiled' ][ $plugin_name ][ 'modifier' ])) { + $this->required_plugins[ 'nocache' ][ $plugin_name ][ 'modifier' ] = + $this->required_plugins[ 'compiled' ][ $plugin_name ][ 'modifier' ]; } } } else { @@ -1266,6 +1287,65 @@ abstract class Smarty_Internal_TemplateCompilerBase return $code; } + /** + * Save current required plugins + * + * @param bool $init if true init required plugins + */ + public function saveRequiredPlugins($init=false) + { + $this->required_plugins_stack[] = $this->required_plugins; + if ($init) { + $this->required_plugins = array('compiled' => array(), 'nocache' => array()); + } + } + + /** + * Restore required plugins + */ + public function restoreRequiredPlugins() + { + $this->required_plugins = array_pop($this->required_plugins_stack); + } + + /** + * Compile code to call Smarty_Internal_Template::_checkPlugins() + * for required plugins + * + * @return string + */ + public function compileRequiredPlugins() + { + $code = $this->compileCheckPlugins($this->required_plugins[ 'compiled' ]); + if ($this->caching && !empty($this->required_plugins[ 'nocache' ])) { + $code .= $this->makeNocacheCode($this->compileCheckPlugins($this->required_plugins[ 'nocache' ])); + } + return $code; + } + + /** + * Compile code to call Smarty_Internal_Template::_checkPlugins + * - checks if plugin is callable require otherwise + * + * @param $requiredPlugins + * + * @return string + */ + public function compileCheckPlugins($requiredPlugins) + { + if (!empty($requiredPlugins)) { + $plugins = array(); + foreach ($requiredPlugins as $plugin) { + foreach ($plugin as $data) { + $plugins[] = $data; + } + } + return '$_smarty_tpl->_checkPlugins(' . $this->getVarExport($plugins) . ');' . "\n"; + } else { + return ''; + } + } + /** * method to compile a Smarty template * diff --git a/libs/sysplugins/smarty_template_resource_base.php b/libs/sysplugins/smarty_template_resource_base.php index eb262ab0..951e02af 100644 --- a/libs/sysplugins/smarty_template_resource_base.php +++ b/libs/sysplugins/smarty_template_resource_base.php @@ -72,13 +72,6 @@ abstract class Smarty_Template_Resource_Base */ public $content = null; - /** - * required plugins - * - * @var array - */ - public $required_plugins = array(); - /** * Included sub templates * - index name