mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-04 18:34:27 +02:00
- optimization of inheritance processing
This commit is contained in:
@@ -1,4 +1,7 @@
|
||||
===== 3.1.30-dev ===== (xx.xx.xx)
|
||||
10.05.2016
|
||||
- optimization of inheritance processing
|
||||
|
||||
07.05.2016
|
||||
-bugfix Only variables should be assigned by reference https://github.com/smarty-php/smarty/issues/227
|
||||
|
||||
|
@@ -121,7 +121,7 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
/**
|
||||
* smarty version
|
||||
*/
|
||||
const SMARTY_VERSION = '3.1.30-dev/67';
|
||||
const SMARTY_VERSION = '3.1.30-dev/68';
|
||||
|
||||
/**
|
||||
* define variable scopes
|
||||
|
@@ -77,69 +77,13 @@ class Smarty_Internal_Block
|
||||
* - if outer level {block} of child template ($state == 1) save it as child root block
|
||||
* - otherwise process inheritance and render
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl
|
||||
* @param int|null $tplIndex index of outer level {block} if nested
|
||||
* @param string $name block name
|
||||
* @param int|null $tplIndex index of outer level {block} if nested
|
||||
*/
|
||||
public function __construct(Smarty_Internal_Template $tpl, $name, $tplIndex = null)
|
||||
public function __construct($name, $tplIndex)
|
||||
{
|
||||
$this->name = $name;
|
||||
$inheritance = &$tpl->ext->_inheritance;
|
||||
$this->tplIndex = $tplIndex ? $tplIndex : $inheritance->tplIndex;
|
||||
if (isset($inheritance->childRoot[ $this->name ])) {
|
||||
$this->child = $inheritance->childRoot[ $this->name ];
|
||||
}
|
||||
if ($inheritance->state == 1) {
|
||||
$inheritance->childRoot[ $this->name ] = $this;
|
||||
return;
|
||||
}
|
||||
// make sure we got child block of child template of current block
|
||||
while ($this->child && $this->tplIndex <= $this->child->tplIndex) {
|
||||
$this->child = $this->child->child;
|
||||
}
|
||||
$this->process($tpl);
|
||||
}
|
||||
|
||||
/**
|
||||
* Goto child block or render this
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl
|
||||
* @param \Smarty_Internal_Block|null $parent
|
||||
*/
|
||||
public function process(Smarty_Internal_Template $tpl, Smarty_Internal_Block $parent = null)
|
||||
{
|
||||
$inheritance = &$tpl->ext->_inheritance;
|
||||
if ($this->hide && !isset($this->child)) {
|
||||
return;
|
||||
}
|
||||
if (isset($this->child) && $this->child->hide && !isset($this->child->child)) {
|
||||
$this->child = null;
|
||||
}
|
||||
$this->parent = $parent;
|
||||
if ($this->append && !$this->prepend && isset($parent)) {
|
||||
$this->callParent($tpl);
|
||||
}
|
||||
if ($this->callsChild || !isset($this->child) || ($this->child->hide && !isset($this->child->child))) {
|
||||
$this->subTemplateNesting = 0;
|
||||
array_unshift($inheritance->blockCallStack, $this);
|
||||
$this->callBlock($tpl);
|
||||
array_shift($inheritance->blockCallStack);
|
||||
} else {
|
||||
$this->child->process($tpl, $this);
|
||||
}
|
||||
if ($this->prepend && isset($parent)) {
|
||||
$this->callParent($tpl);
|
||||
if ($this->append) {
|
||||
if ($this->callsChild || !isset($this->child) || ($this->child->hide && !isset($this->child->child))) {
|
||||
$this->subTemplateNesting = 0;
|
||||
array_unshift($inheritance->blockCallStack, $this);
|
||||
$this->callBlock($tpl);
|
||||
array_shift($inheritance->blockCallStack);
|
||||
} else {
|
||||
$this->child->process($tpl, $this);
|
||||
}
|
||||
}
|
||||
}
|
||||
$this->parent = null;
|
||||
$this->tplIndex = $tplIndex;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -150,35 +94,4 @@ class Smarty_Internal_Block
|
||||
public function callBlock(Smarty_Internal_Template $tpl)
|
||||
{
|
||||
}
|
||||
|
||||
/**
|
||||
* Render child on {$smarty.block.child}
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl
|
||||
*/
|
||||
public function callChild(Smarty_Internal_Template $tpl)
|
||||
{
|
||||
if (isset($this->child)) {
|
||||
$this->child->process($tpl, $this);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render parent on {$smarty.block.parent} or {block append/prepend} *
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl
|
||||
*
|
||||
* @throws \SmartyException
|
||||
*/
|
||||
public function callParent(Smarty_Internal_Template $tpl)
|
||||
{
|
||||
if (isset($this->parent)) {
|
||||
$this->parent->subTemplateNesting = 0;
|
||||
array_unshift($tpl->ext->_inheritance->blockCallStack, $this->parent);
|
||||
$this->parent->callBlock($tpl);
|
||||
array_shift($tpl->ext->_inheritance->blockCallStack);
|
||||
} else {
|
||||
throw new SmartyException("inheritance: illegal {\$smarty.block.parent} or {block append/prepend} used in parent template '{$tpl->ext->_inheritance->sources[$this->tplIndex]->filepath}' block '{$this->name}'");
|
||||
}
|
||||
}
|
||||
}
|
@@ -121,7 +121,7 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_Compile_Shared_Inher
|
||||
$compiler->has_code = true;
|
||||
$compiler->suppressNocacheProcessing = true;
|
||||
$compiler->_cache[ 'blockParams' ][ $compiler->_cache[ 'blockNesting' ] ][ 'callsChild' ] = 'true';
|
||||
$output = "<?php \n\$this->callChild(\$_smarty_tpl);\n?>\n";
|
||||
$output = "<?php \n\$_smarty_tpl->inheritance->callChild(\$_smarty_tpl, \$this);\n?>\n";
|
||||
return $output;
|
||||
}
|
||||
|
||||
@@ -141,7 +141,7 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_Compile_Shared_Inher
|
||||
}
|
||||
$compiler->suppressNocacheProcessing = true;
|
||||
$compiler->has_code = true;
|
||||
$output = "<?php \n\$this->callParent(\$_smarty_tpl);\n?>\n";
|
||||
$output = "<?php \n\$_smarty_tpl->inheritance->callParent(\$_smarty_tpl, \$this);\n?>\n";
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
@@ -180,16 +180,9 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_Compile_Shared_
|
||||
$_functionCode = $compiler->parser->current_buffer;
|
||||
// setup buffer for template function code
|
||||
$compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
|
||||
if ($compiler->template->source->type == 'file') {
|
||||
$sourceInfo = $compiler->template->source->filepath;
|
||||
} else {
|
||||
$basename = $compiler->template->source->handler->getBasename($compiler->template->source);
|
||||
$sourceInfo =
|
||||
$compiler->template->source->type . ':' . ($basename ? $basename : $compiler->template->source->name);
|
||||
}
|
||||
|
||||
$output = "<?php\n";
|
||||
$output .= "/* {block {$_name}} {$sourceInfo} */\n";
|
||||
$output .= "/* {block {$_name}} */\n";
|
||||
$output .= "class {$_className} extends Smarty_Internal_Block\n";
|
||||
$output .= "{\n";
|
||||
foreach ($_block as $property => $value) {
|
||||
@@ -238,9 +231,9 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_Compile_Shared_
|
||||
$compiler->parser->current_buffer = $_buffer;
|
||||
$output = "<?php \n";
|
||||
if ($compiler->_cache[ 'blockNesting' ] == 1) {
|
||||
$output .= "new {$_className}(\$_smarty_tpl, $_name);\n";
|
||||
$output .= "\$_smarty_tpl->inheritance->instanceBlock(\$_smarty_tpl, '$_className', $_name);\n";
|
||||
} else {
|
||||
$output .= "new {$_className}(\$_smarty_tpl, $_name, \$this->tplIndex);\n";
|
||||
$output .= "\$_smarty_tpl->inheritance->instanceBlock(\$_smarty_tpl, '$_className', $_name, \$this->tplIndex);\n";
|
||||
}
|
||||
$output .= "?>\n";
|
||||
$compiler->_cache[ 'blockNesting' ] --;
|
||||
|
@@ -99,7 +99,7 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_Compile_Shared_Inh
|
||||
private function compileEndChild(Smarty_Internal_TemplateCompilerBase $compiler)
|
||||
{
|
||||
$compiler->parser->template_postfix[] = new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
||||
"<?php \$_smarty_tpl->ext->_inheritance->endChild(\$_smarty_tpl);\n?>\n");
|
||||
"<?php \$_smarty_tpl->inheritance->endChild(\$_smarty_tpl);\n?>\n");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -297,8 +297,8 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
||||
if (!($tpl->source->handler->uncompiled) && $tpl->source->exists) {
|
||||
$compiler->parent_compiler->mergedSubTemplatesData[ $uid ][ $t_hash ][ 'uid' ] =
|
||||
$tpl->source->uid;
|
||||
if (isset($compiler->template->ext->_inheritance)) {
|
||||
$tpl->ext->_inheritance = clone $compiler->template->ext->_inheritance;
|
||||
if (isset($compiler->template->inheritance)) {
|
||||
$tpl->inheritance = clone $compiler->template->inheritance;
|
||||
}
|
||||
$tpl->compiled = new Smarty_Template_Compiled();
|
||||
$tpl->compiled->nocache_hash = $compiler->parent_compiler->template->compiled->nocache_hash;
|
||||
|
@@ -40,7 +40,7 @@ class Smarty_Internal_Compile_Shared_Inheritance extends Smarty_Internal_Compile
|
||||
*/
|
||||
static function postCompile(Smarty_Internal_TemplateCompilerBase $compiler, $initChildSequence = false)
|
||||
{
|
||||
$compiler->prefixCompiledCode .= "<?php \$_smarty_tpl->ext->_inheritance->init(\$_smarty_tpl, " .
|
||||
$compiler->prefixCompiledCode .= "<?php \$_smarty_tpl->_loadInheritance();\n\$_smarty_tpl->inheritance->init(\$_smarty_tpl, " .
|
||||
var_export($initChildSequence, true) . ");\n?>\n";
|
||||
}
|
||||
}
|
@@ -10,7 +10,6 @@
|
||||
* @subpackage PluginsInternal
|
||||
* @author Uwe Tews
|
||||
*
|
||||
* @property Smarty_Internal_Runtime_Inheritance $_inheritance
|
||||
* @property Smarty_Internal_Runtime_TplFunction $_tplFunction
|
||||
* @property Smarty_Internal_Runtime_Foreach $_foreach
|
||||
* @property Smarty_Internal_Runtime_WriteFile $_writeFile
|
||||
|
@@ -45,7 +45,7 @@ class Smarty_Internal_Resource_File extends Smarty_Resource
|
||||
}
|
||||
$parentPath = $_template->parent->source->filepath;
|
||||
// if we are inside an {block} tag the path must be relative to template of {block}
|
||||
if (isset($_template->ext->_inheritance) && $path = $_template->ext->_inheritance->getBlockFilepath()) {
|
||||
if (isset($_template->inheritance) && $path = $_template->inheritance->getBlockFilepath()) {
|
||||
$parentPath = $path;
|
||||
}
|
||||
// normalize path
|
||||
|
@@ -71,8 +71,8 @@ class Smarty_Internal_Runtime_Inheritance
|
||||
{
|
||||
// if called while executing parent template it must be a sub-template with new inheritance root
|
||||
if ($initChild && $this->state == 3 && (strpos($tpl->template_resource, 'extendsall') === false)) {
|
||||
$tpl->ext->_inheritance = new Smarty_Internal_Runtime_Inheritance();
|
||||
$tpl->ext->_inheritance->init($tpl, $initChild, $blockNames);
|
||||
$tpl->inheritance = new Smarty_Internal_Runtime_Inheritance();
|
||||
$tpl->inheritance->init($tpl, $initChild, $blockNames);
|
||||
return;
|
||||
}
|
||||
// start of child sub template(s)
|
||||
@@ -83,6 +83,8 @@ class Smarty_Internal_Runtime_Inheritance
|
||||
ob_start();
|
||||
}
|
||||
$this->inheritanceLevel ++;
|
||||
$tpl->startRenderCallbacks[ 'inheritance' ] = array($this, 'subTemplateStart');
|
||||
$tpl->endRenderCallbacks[ 'inheritance' ] = array($this, 'subTemplateEnd');
|
||||
}
|
||||
// in parent state {include} will not increment template index
|
||||
if ($this->state != 3) {
|
||||
@@ -110,6 +112,114 @@ class Smarty_Internal_Runtime_Inheritance
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Smarty_Internal_Block constructor.
|
||||
* - if outer level {block} of child template ($state == 1) save it as child root block
|
||||
* - otherwise process inheritance and render
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl
|
||||
* @param $className
|
||||
* @param string $name
|
||||
* @param int|null $tplIndex index of outer level {block} if nested
|
||||
*/
|
||||
public function instanceBlock(Smarty_Internal_Template $tpl, $className, $name, $tplIndex = null)
|
||||
{
|
||||
$block = new $className($name, $tplIndex ? $tplIndex : $this->tplIndex);
|
||||
if (isset($this->childRoot[ $name ])) {
|
||||
$block->child = $this->childRoot[ $name ];
|
||||
}
|
||||
if ($this->state == 1) {
|
||||
$this->childRoot[ $name ] = $block;
|
||||
return;
|
||||
}
|
||||
// make sure we got child block of child template of current block
|
||||
while ($block->child && $block->tplIndex <= $block->child->tplIndex) {
|
||||
$block->child = $block->child->child;
|
||||
}
|
||||
$this->process($tpl, $block);
|
||||
}
|
||||
|
||||
/**
|
||||
* Goto child block or render this
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl
|
||||
* @param \Smarty_Internal_Block $block
|
||||
* @param \Smarty_Internal_Block|null $parent
|
||||
*
|
||||
* @throws \SmartyException
|
||||
*/
|
||||
public function process(Smarty_Internal_Template $tpl, Smarty_Internal_Block $block,
|
||||
Smarty_Internal_Block $parent = null)
|
||||
{
|
||||
if ($block->hide && !isset($block->child)) {
|
||||
return;
|
||||
}
|
||||
if (isset($block->child) && $block->child->hide && !isset($block->child->child)) {
|
||||
$block->child = null;
|
||||
}
|
||||
$block->parent = $parent;
|
||||
if ($block->append && !$block->prepend && isset($parent)) {
|
||||
$this->callParent($tpl, $block);
|
||||
}
|
||||
if ($block->callsChild || !isset($block->child) || ($block->child->hide && !isset($block->child->child))) {
|
||||
$block->subTemplateNesting = 0;
|
||||
$this->blockCallStack[] = $block;
|
||||
$block->callBlock($tpl);
|
||||
array_pop($this->blockCallStack);
|
||||
} else {
|
||||
$this->process($tpl, $block->child, $block);
|
||||
}
|
||||
if ($block->prepend && isset($parent)) {
|
||||
$this->callParent($tpl, $block);
|
||||
if ($block->append) {
|
||||
if ($block->callsChild || !isset($block->child) ||
|
||||
($block->child->hide && !isset($block->child->child))
|
||||
) {
|
||||
$block->subTemplateNesting = 0;
|
||||
$this->blockCallStack[] = $block;
|
||||
$block->callBlock($tpl);
|
||||
array_pop($this->blockCallStack);
|
||||
} else {
|
||||
$this->process($tpl, $block->child, $block);
|
||||
}
|
||||
}
|
||||
}
|
||||
$block->parent = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Render child on {$smarty.block.child}
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl
|
||||
* @param \Smarty_Internal_Block $block
|
||||
*/
|
||||
public function callChild(Smarty_Internal_Template $tpl, Smarty_Internal_Block $block)
|
||||
{
|
||||
if (isset($block->child)) {
|
||||
$this->process($tpl, $block->child, $block);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render parent on {$smarty.block.parent} or {block append/prepend} *
|
||||
*
|
||||
* @param \Smarty_Internal_Template $tpl
|
||||
* @param \Smarty_Internal_Block $block
|
||||
*
|
||||
* @throws \SmartyException
|
||||
*/
|
||||
public function callParent(Smarty_Internal_Template $tpl, Smarty_Internal_Block $block)
|
||||
{
|
||||
if (isset($block->parent)) {
|
||||
$block->parent->subTemplateNesting = 0;
|
||||
$this->blockCallStack[] = $block->parent;
|
||||
$block->parent->callBlock($tpl);
|
||||
array_pop($this->blockCallStack);
|
||||
} 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}'");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return source filepath of current {block} if not in sub-template
|
||||
*
|
||||
@@ -117,8 +227,9 @@ class Smarty_Internal_Runtime_Inheritance
|
||||
*/
|
||||
public function getBlockFilepath()
|
||||
{
|
||||
if (!empty($this->blockCallStack) && $this->blockCallStack[ 0 ]->subTemplateNesting === 0) {
|
||||
return $this->sources[ $this->blockCallStack[ 0 ]->tplIndex ]->filepath;
|
||||
$count = count($this->blockCallStack);
|
||||
if ($count && $this->blockCallStack[ $count - 1 ]->subTemplateNesting === 0) {
|
||||
return $this->sources[ $this->blockCallStack[ $count - 1 ]->tplIndex ]->filepath;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@@ -128,8 +239,9 @@ class Smarty_Internal_Runtime_Inheritance
|
||||
*/
|
||||
public function subTemplateStart()
|
||||
{
|
||||
if (!empty($this->blockCallStack)) {
|
||||
$this->blockCallStack[ 0 ]->subTemplateNesting ++;
|
||||
$count = count($this->blockCallStack);
|
||||
if ($count) {
|
||||
$this->blockCallStack[ $count - 1 ]->subTemplateNesting ++;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,8 +250,9 @@ class Smarty_Internal_Runtime_Inheritance
|
||||
*/
|
||||
public function subTemplateEnd()
|
||||
{
|
||||
if (!empty($this->blockCallStack)) {
|
||||
$this->blockCallStack[ 0 ]->subTemplateNesting --;
|
||||
$count = count($this->blockCallStack);
|
||||
if ($count && $this->blockCallStack[ $count - 1 ]->subTemplateNesting) {
|
||||
$this->blockCallStack[ $count - 1 ]->subTemplateNesting --;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@@ -46,6 +46,13 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
*/
|
||||
public $source = null;
|
||||
|
||||
/**
|
||||
* Inheritance runtime extension
|
||||
*
|
||||
* @var Smarty_Internal_Runtime_Inheritance
|
||||
*/
|
||||
public $inheritance = null;
|
||||
|
||||
/**
|
||||
* Template resource
|
||||
*
|
||||
@@ -256,7 +263,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
$smarty = &$this->smarty;
|
||||
$_templateId = $smarty->_getTemplateId($template, $cache_id, $compile_id, $caching, $tpl);
|
||||
// recursive call ?
|
||||
if ($tpl->_getTemplateId() != $_templateId) {
|
||||
if (isset($tpl->templateId) ? $tpl->templateId : $tpl->_getTemplateId() != $_templateId) {
|
||||
// already in template cache?
|
||||
if (isset($smarty->_cache[ 'tplObjects' ][ $_templateId ])) {
|
||||
// copy data from cached object
|
||||
@@ -330,10 +337,6 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
}
|
||||
}
|
||||
$tpl->_cache = array();
|
||||
if (isset($tpl->ext->_inheritance)) {
|
||||
$saved_inheritance = $tpl->ext->_inheritance;
|
||||
$saved_inheritance->subTemplateStart();
|
||||
}
|
||||
if (isset($uid)) {
|
||||
if ($smarty->debugging) {
|
||||
$smarty->_debug->start_template($tpl);
|
||||
@@ -351,12 +354,6 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
$tpl->render();
|
||||
}
|
||||
}
|
||||
if (isset($saved_inheritance)) {
|
||||
$saved_inheritance->subTemplateEnd();
|
||||
$tpl->ext->_inheritance = $saved_inheritance;
|
||||
} else {
|
||||
unset($tpl->ext->_inheritance);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -553,6 +550,29 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load inheritance object
|
||||
*
|
||||
*/
|
||||
public function _loadInheritance()
|
||||
{
|
||||
if (!isset($this->inheritance)) {
|
||||
$this->inheritance = new Smarty_Internal_Runtime_Inheritance();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Unload inheritance object
|
||||
*
|
||||
*/
|
||||
public function _cleanUp()
|
||||
{
|
||||
$this->tpl_function = array();
|
||||
$this->startRenderCallbacks = array();
|
||||
$this->endRenderCallbacks = array();
|
||||
$this->inheritance = null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Load compiler object
|
||||
*
|
||||
|
@@ -198,9 +198,8 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
|
||||
$template->tpl_vars = array_merge(Smarty::$global_tpl_vars, $template->tpl_vars);
|
||||
}
|
||||
$result = $template->render(false, $function);
|
||||
unset($template->ext->_inheritance);
|
||||
$template->tpl_function = array();
|
||||
if ($saveVars) {
|
||||
$template->_cleanUp();
|
||||
if ($saveVars) {
|
||||
$template->tpl_vars = $savedTplVars;
|
||||
$template->config_vars = $savedConfigVars;
|
||||
} else {
|
||||
|
@@ -216,7 +216,7 @@ abstract class Smarty_Resource
|
||||
) {
|
||||
$parentPath = $obj->parent->source->filepath;
|
||||
// if we are inside an {block} tag the path must be relative to template of {block}
|
||||
if (isset($obj->ext->_inheritance) && $path = $obj->ext->_inheritance->getBlockFilepath()) {
|
||||
if (isset($obj->inheritance) && $path = $obj->inheritance->getBlockFilepath()) {
|
||||
$parentPath = $path;
|
||||
}
|
||||
$name = $smarty->_realpath(dirname($parentPath) . DS . $name);
|
||||
|
Reference in New Issue
Block a user