From 4de72f1acdf9bd6b31a566fa4ac182f4e0d9eca4 Mon Sep 17 00:00:00 2001 From: uwetews Date: Thu, 29 Sep 2016 04:22:20 +0200 Subject: [PATCH] - improvement new Smarty::$extends_recursion property to disable execution of {extends} in templates called by extends resource https://github.com/smarty-php/smarty/issues/296 --- libs/Smarty.class.php | 8 ++++++ .../smarty_internal_compile_extends.php | 24 ++++++++++++------ .../smarty_internal_runtime_inheritance.php | 25 ++++++++++++++++--- libs/sysplugins/smarty_template_compiled.php | 3 ++- 4 files changed, 49 insertions(+), 11 deletions(-) diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index a994d7f3..3805c770 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -432,6 +432,14 @@ class Smarty extends Smarty_Internal_TemplateBase */ public $merge_compiled_includes = false; + /* + * flag for behaviour when extends: resource and {extends} tag are used simultaneous + * if false disable execution of {extends} in templates called by extends resource. + * (behaviour as versions < 3.1.28) + * + * @var boolean + */ + public $extends_recursion = true; /** * force cache file creation * diff --git a/libs/sysplugins/smarty_internal_compile_extends.php b/libs/sysplugins/smarty_internal_compile_extends.php index 949875c5..83cb8050 100644 --- a/libs/sysplugins/smarty_internal_compile_extends.php +++ b/libs/sysplugins/smarty_internal_compile_extends.php @@ -84,8 +84,7 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_Compile_Shared_Inh $this->compileEndChild($compiler); } } else { - $this->compileEndChild($compiler); - $this->compileInclude($compiler, $_attr[ 'file' ]); + $this->compileEndChild($compiler, $_attr[ 'file' ]); } $compiler->has_code = false; return ''; @@ -95,24 +94,35 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_Compile_Shared_Inh * Add code for inheritance endChild() method to end of template * * @param \Smarty_Internal_TemplateCompilerBase $compiler + * @param null|string $template optional inheritance parent template */ - private function compileEndChild(Smarty_Internal_TemplateCompilerBase $compiler) + private function compileEndChild(Smarty_Internal_TemplateCompilerBase $compiler, $template = null) { + $inlineUids = ''; + if (isset($template) && $compiler->smarty->merge_compiled_includes) { + $code = $compiler->compileTag('include', array($template, array('scope' => 'parent'))); + if (preg_match("/([,][\s]*['][a-z0-9]+['][,][\s]*[']content.*['])[)]/", $code, $match)) { + $inlineUids = $match[ 1 ]; + } + } $compiler->parser->template_postfix[] = new Smarty_Internal_ParseTree_Tag($compiler->parser, - "inheritance->endChild();\n?>\n"); + "inheritance->endChild(\$_smarty_tpl" . + (isset($template) ? + ', ' . $template . $inlineUids : + '') . ");\n?>\n"); } /** * Add code for including subtemplate to end of template * * @param \Smarty_Internal_TemplateCompilerBase $compiler - * @param string $file subtemplate name + * @param string $template subtemplate name */ - private function compileInclude(Smarty_Internal_TemplateCompilerBase $compiler, $file) + private function compileInclude(Smarty_Internal_TemplateCompilerBase $compiler, $template) { $compiler->parser->template_postfix[] = new Smarty_Internal_ParseTree_Tag($compiler->parser, $compiler->compileTag('include', - array($file, + array($template, array('scope' => 'parent')))); } diff --git a/libs/sysplugins/smarty_internal_runtime_inheritance.php b/libs/sysplugins/smarty_internal_runtime_inheritance.php index 36e8ab35..e49b9889 100644 --- a/libs/sysplugins/smarty_internal_runtime_inheritance.php +++ b/libs/sysplugins/smarty_internal_runtime_inheritance.php @@ -99,14 +99,22 @@ class Smarty_Internal_Runtime_Inheritance * End of child template(s) * - if outer level is reached flush output buffer and switch to wait for parent template state * + * @param \Smarty_Internal_Template $tpl + * @param null|string $template optinal name of inheritance parent template + * @param null|string $uid uid of inline template + * @param null|string $func function call name of inline template */ - public function endChild() + public function endChild(Smarty_Internal_Template $tpl, $template = null, $uid = null, $func = null) { $this->inheritanceLevel --; if (!$this->inheritanceLevel) { ob_end_clean(); $this->state = 2; } + if (isset($template) && ($tpl->parent->source->type !== 'extends' || $tpl->smarty->extends_recursion)) { + $tpl->_subTemplateRender($template, $tpl->cache_id, $tpl->compile_id, $tpl->caching ? 9999 : 0, + $tpl->cache_lifetime, array(), 2, false, $uid, $func); + } } /** @@ -197,11 +205,22 @@ class Smarty_Internal_Runtime_Inheritance * @param \Smarty_Internal_Template $tpl * @param \Smarty_Internal_Block $block * + * @param null $name + * * @throws \SmartyException */ - public function callParent(Smarty_Internal_Template $tpl, Smarty_Internal_Block $block) + public function callParent(Smarty_Internal_Template $tpl, Smarty_Internal_Block $block, $name = null) { - if (isset($block->parent)) { + if (isset($name)) { + $block = $block->parent; + while (isset($block)) { + if (isset($block->subBlocks[ $name ])) { + } else { + $block = $block->parent; + } + } + return; + } else if (isset($block->parent)) { $this->callBlock($block->parent, $tpl); } else { throw new SmartyException("inheritance: illegal {\$smarty.block.parent} or {block append/prepend} used in parent template '{$tpl->inheritance->sources[$block->tplIndex]->filepath}' block '{$block->name}'"); diff --git a/libs/sysplugins/smarty_template_compiled.php b/libs/sysplugins/smarty_template_compiled.php index 432b6723..b40e3774 100644 --- a/libs/sysplugins/smarty_template_compiled.php +++ b/libs/sysplugins/smarty_template_compiled.php @@ -61,7 +61,8 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base $this->filepath .= (int) $smarty->config_read_hidden + (int) $smarty->config_booleanize * 2 + (int) $smarty->config_overwrite * 4; } else { - $this->filepath .= (int) $smarty->merge_compiled_includes + (int) $smarty->escape_html * 2; + $this->filepath .= (int) $smarty->merge_compiled_includes + (int) $smarty->escape_html * 2 + + (($smarty->merge_compiled_includes && $source->type === 'extends') ? (int) $smarty->extends_recursion * 4 : 0); } $this->filepath .= '.' . $source->type; $basename = $source->handler->getBasename($source);