mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-05 19:04:27 +02:00
- rework of template inheritance
This commit is contained in:
@@ -1,6 +1,7 @@
|
|||||||
===== 3.1.28-dev===== (xx.xx.2015)
|
===== 3.1.28-dev===== (xx.xx.2015)
|
||||||
18.10.2015
|
18.10.2015
|
||||||
- optimize filepath normalization
|
- optimize filepath normalization
|
||||||
|
- rework of template inheritance
|
||||||
|
|
||||||
18.09.2015
|
18.09.2015
|
||||||
- bugfix {if $foo instanceof $bar} failed to compile if 2nd value is a variable https://github.com/smarty-php/smarty/issues/92
|
- bugfix {if $foo instanceof $bar} failed to compile if 2nd value is a variable https://github.com/smarty-php/smarty/issues/92
|
||||||
|
@@ -13,7 +13,7 @@
|
|||||||
*
|
*
|
||||||
* @author Uwe Tews <uwe.tews@googlemail.com>
|
* @author Uwe Tews <uwe.tews@googlemail.com>
|
||||||
*/
|
*/
|
||||||
class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
|
class Smarty_Internal_Compile_Block extends Smarty_Internal_Compile_Shared_Inheritance
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Attribute definition: Overwrites base class.
|
* Attribute definition: Overwrites base class.
|
||||||
@@ -45,7 +45,7 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
|
|||||||
* @var array
|
* @var array
|
||||||
* @see Smarty_Internal_CompileBase
|
* @see Smarty_Internal_CompileBase
|
||||||
*/
|
*/
|
||||||
public $optional_attributes = array();
|
public $optional_attributes = array('assign');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* nesting level of block tags
|
* nesting level of block tags
|
||||||
@@ -54,6 +54,13 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
|
|||||||
*/
|
*/
|
||||||
public static $blockTagNestingLevel = 0;
|
public static $blockTagNestingLevel = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Saved compiler object
|
||||||
|
*
|
||||||
|
* @var Smarty_Internal_TemplateCompilerBase
|
||||||
|
*/
|
||||||
|
public $compiler = null;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiles code for the {block} tag
|
* Compiles code for the {block} tag
|
||||||
*
|
*
|
||||||
@@ -65,14 +72,22 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
|
|||||||
*/
|
*/
|
||||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||||
{
|
{
|
||||||
if ($compiler->blockTagNestingLevel == 0 && $compiler->inheritanceChild) {
|
if (!isset($compiler->_cache['blockNesting'])) {
|
||||||
|
$compiler->_cache['blockNesting'] = 0;
|
||||||
|
}
|
||||||
|
if ($compiler->_cache['blockNesting'] == 0) {
|
||||||
|
// make sure that inheritance gets initialized in template code
|
||||||
|
$this->registerInit($compiler);
|
||||||
$this->option_flags = array('hide', 'nocache', 'append', 'prepend');
|
$this->option_flags = array('hide', 'nocache', 'append', 'prepend');
|
||||||
} else {
|
} else {
|
||||||
$this->option_flags = array('hide', 'nocache');
|
$this->option_flags = array('hide', 'nocache');
|
||||||
}
|
}
|
||||||
// check and get attributes
|
// check and get attributes
|
||||||
$_attr = $this->getAttributes($compiler, $args);
|
$_attr = $this->getAttributes($compiler, $args);
|
||||||
$compiler->blockTagNestingLevel ++;
|
$compiler->_cache['blockNesting'] ++;
|
||||||
|
$compiler->_cache['blockName'][$compiler->_cache['blockNesting']] = $_attr['name'];
|
||||||
|
$compiler->_cache['blockParams'][$compiler->_cache['blockNesting']][0] = 'block_' . preg_replace('![^\w]+!', '_', uniqid(rand(), true));
|
||||||
|
$compiler->_cache['blockParams'][$compiler->_cache['blockNesting']][1] = false;
|
||||||
$this->openTag($compiler, 'block', array($_attr, $compiler->nocache, $compiler->parser->current_buffer,
|
$this->openTag($compiler, 'block', array($_attr, $compiler->nocache, $compiler->parser->current_buffer,
|
||||||
$compiler->template->compiled->has_nocache_code,
|
$compiler->template->compiled->has_nocache_code,
|
||||||
$compiler->template->caching));
|
$compiler->template->caching));
|
||||||
@@ -100,15 +115,15 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
|
|||||||
*/
|
*/
|
||||||
static function compileChildBlock(Smarty_Internal_TemplateCompilerBase $compiler, $_name = null)
|
static function compileChildBlock(Smarty_Internal_TemplateCompilerBase $compiler, $_name = null)
|
||||||
{
|
{
|
||||||
if (!$compiler->blockTagNestingLevel) {
|
if (!isset($compiler->_cache['blockNesting'])) {
|
||||||
$compiler->trigger_template_error(' tag {$smarty.block.child} used outside {block} tags ',
|
$compiler->trigger_template_error(' tag {$smarty.block.child} used outside {block} tags ',
|
||||||
$compiler->parser->lex->taglineno);
|
$compiler->parser->lex->taglineno);
|
||||||
}
|
}
|
||||||
$compiler->has_code = true;
|
$compiler->has_code = true;
|
||||||
$compiler->suppressNocacheProcessing = true;
|
$compiler->suppressNocacheProcessing = true;
|
||||||
$compiler->callChildBlock[$compiler->blockTagNestingLevel] = true;
|
$compiler->_cache['blockParams'][$compiler->_cache['blockNesting']][1] = true;
|
||||||
$_output = "<?php \n\$_smarty_tpl->_Block->callChildBlock(\$_smarty_tpl, \$block);?>";
|
$output = "<?php \n\$_smarty_tpl->_inheritance->processBlock(\$_smarty_tpl, 2, {$compiler->_cache['blockName'][$compiler->_cache['blockNesting']]}, null, \$_blockParentStack);\n?>\n";
|
||||||
return $_output;
|
return $output;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -121,18 +136,14 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
|
|||||||
*/
|
*/
|
||||||
static function compileParentBlock(Smarty_Internal_TemplateCompilerBase $compiler, $_name = null)
|
static function compileParentBlock(Smarty_Internal_TemplateCompilerBase $compiler, $_name = null)
|
||||||
{
|
{
|
||||||
if (!$compiler->inheritanceChild) {
|
if (!isset($compiler->_cache['blockNesting'])) {
|
||||||
$compiler->trigger_template_error(' tag {$smarty.block.parent} used in parent template ',
|
|
||||||
$compiler->parser->lex->taglineno);
|
|
||||||
}
|
|
||||||
if (!$compiler->blockTagNestingLevel) {
|
|
||||||
$compiler->trigger_template_error(' tag {$smarty.block.parent} used outside {block} tags ',
|
$compiler->trigger_template_error(' tag {$smarty.block.parent} used outside {block} tags ',
|
||||||
$compiler->parser->lex->taglineno);
|
$compiler->parser->lex->taglineno);
|
||||||
}
|
}
|
||||||
$compiler->suppressNocacheProcessing = true;
|
$compiler->suppressNocacheProcessing = true;
|
||||||
$compiler->has_code = true;
|
$compiler->has_code = true;
|
||||||
$_output = "<?php \n\$_smarty_tpl->_Block->callParentBlock(\$_smarty_tpl, \$block);?>";
|
$output = "<?php \n\$_smarty_tpl->_inheritance->processBlock(\$_smarty_tpl, 3, {$compiler->_cache['blockName'][$compiler->_cache['blockNesting']]}, null, \$_blockParentStack);\n?>\n";
|
||||||
return $_output;
|
return $output;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,7 +151,7 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
|
|||||||
* Smarty Internal Plugin Compile BlockClose Class
|
* Smarty Internal Plugin Compile BlockClose Class
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase
|
class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_Compile_Shared_Inheritance
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Compiles code for the {/block} tag
|
* Compiles code for the {/block} tag
|
||||||
@@ -153,57 +164,83 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase
|
|||||||
*/
|
*/
|
||||||
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
public function compile($args, Smarty_Internal_TemplateCompilerBase $compiler, $parameter)
|
||||||
{
|
{
|
||||||
$this->compiler = $compiler;
|
|
||||||
list($_attr, $_nocache, $_buffer, $_has_nocache_code, $_caching) = $this->closeTag($compiler, array('block'));
|
list($_attr, $_nocache, $_buffer, $_has_nocache_code, $_caching) = $this->closeTag($compiler, array('block'));
|
||||||
$_name = trim($_attr['name'], "'\"");
|
// init block parameter
|
||||||
|
$_block = $compiler->_cache['blockParams'][$compiler->_cache['blockNesting']];
|
||||||
|
unset($compiler->_cache['blockParams'][$compiler->_cache['blockNesting']]);
|
||||||
|
$_block[2] = $_block[3] = 0;
|
||||||
|
$_name = trim($_attr['name'], "'\"");
|
||||||
|
$_assign = isset($_attr['assign']) ? $_attr['assign'] : null;
|
||||||
|
unset($_attr['assign'], $_attr['name']);
|
||||||
|
foreach ($_attr as $name => $stat) {
|
||||||
|
if ((is_bool($stat) && $stat !== false) || (!is_bool($stat) && $stat != 'false')) {
|
||||||
|
$_block[$name] = is_string($stat) ? trim($stat, "'\"") : $stat;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$_funcName = $_block[0];
|
||||||
|
// get compiled block code
|
||||||
$_functionCode = $compiler->parser->current_buffer;
|
$_functionCode = $compiler->parser->current_buffer;
|
||||||
// setup buffer for template function code
|
// setup buffer for template function code
|
||||||
$compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
|
$compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
|
||||||
|
|
||||||
$_funcNameCaching =
|
|
||||||
$_funcName = preg_replace('![^\w]+!', '_', "block_function_{$_name}_" . uniqid(rand(), true));
|
|
||||||
if ($compiler->template->compiled->has_nocache_code) {
|
if ($compiler->template->compiled->has_nocache_code) {
|
||||||
// $compiler->parent_compiler->template->tpl_function[$_name]['call_name_caching'] = $_funcNameCaching;
|
// $compiler->parent_compiler->template->tpl_function[$_name]['call_name_caching'] = $_funcNameCaching;
|
||||||
$_funcNameCaching .= '_nocache';
|
$_block[6] = $_funcNameCaching = $_funcName . '_nocache';
|
||||||
$output = "<?php\n\n";
|
$output = "<?php\n";
|
||||||
$output .= "/* {block '{$_name}'} {$compiler->template->source->type}:{$compiler->template->source->name} */\n";
|
$output .= "/* {block '{$_name}'} {$compiler->template->source->type}:{$compiler->template->source->name} */\n";
|
||||||
$output .= "function {$_funcNameCaching} (\$_smarty_tpl, \$block) {\n";
|
$output .= "function {$_funcNameCaching} (\$_smarty_tpl, \$_blockParentStack) {\n";
|
||||||
$output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n";
|
$output .= "/*/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n";
|
||||||
$output .= "\$_smarty_tpl->cached->hashes['{$compiler->template->compiled->nocache_hash}'] = true;\n?>\n";
|
$output .= "\$_smarty_tpl->cached->hashes['{$compiler->template->compiled->nocache_hash}'] = true;\n";
|
||||||
|
if (isset($_assign)) {
|
||||||
|
$output .= "ob_start();\n";
|
||||||
|
}
|
||||||
|
$output .= "?>\n";
|
||||||
$compiler->parser->current_buffer->append_subtree($compiler->parser,
|
$compiler->parser->current_buffer->append_subtree($compiler->parser,
|
||||||
new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
||||||
$output));
|
$output));
|
||||||
$compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
|
$compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
|
||||||
$output = "<?php /*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n";
|
$output = "<?php\n";
|
||||||
$output .= "\n}\n";
|
if (isset($_assign)) {
|
||||||
|
$output .= "\$_smarty_tpl->tpl_vars[{$_assign}] = new Smarty_Variable(ob_get_contents());\n";
|
||||||
|
}
|
||||||
|
$output .= "/*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%*/\n";
|
||||||
|
$output .= "}\n";
|
||||||
$output .= "/* {/block '{$_name}'} */\n\n";
|
$output .= "/* {/block '{$_name}'} */\n\n";
|
||||||
$output .= "?>\n";
|
$output .= "?>\n";
|
||||||
$compiler->parser->current_buffer->append_subtree($compiler->parser,
|
$compiler->parser->current_buffer->append_subtree($compiler->parser,
|
||||||
new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
||||||
$output));
|
$output));
|
||||||
$compiler->blockOrFunctionCode .= $f =
|
$compiler->blockOrFunctionCode .= $f = $compiler->parser->current_buffer->to_smarty_php($compiler->parser);
|
||||||
$compiler->parser->current_buffer->to_smarty_php($compiler->parser);
|
|
||||||
$compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
|
$compiler->parser->current_buffer = new Smarty_Internal_ParseTree_Template();
|
||||||
|
$this->compiler = $compiler;
|
||||||
$_functionCode = new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
$_functionCode = new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
||||||
preg_replace_callback("/((<\?php )?echo '\/\*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%\*\/([\S\s]*?)\/\*\/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%\*\/';(\?>\n)?)/",
|
preg_replace_callback("/((<\?php )?echo '\/\*%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%\*\/([\S\s]*?)\/\*\/%%SmartyNocache:{$compiler->template->compiled->nocache_hash}%%\*\/';(\?>\n)?)/",
|
||||||
array($this, 'removeNocache'),
|
array($this, 'removeNocache'),
|
||||||
$_functionCode->to_smarty_php($compiler->parser)));
|
$_functionCode->to_smarty_php($compiler->parser)));
|
||||||
|
$this->compiler = null;
|
||||||
}
|
}
|
||||||
$output = "<?php\n\n";
|
$output = "<?php\n";
|
||||||
$output .= "/* {block '{$_name}'} {$compiler->template->source->type}:{$compiler->template->source->name} */\n";
|
$output .= "/* {block '{$_name}'} {$compiler->template->source->type}:{$compiler->template->source->name} */\n";
|
||||||
$output .= "function {$_funcName}(\$_smarty_tpl, \$block) {?>";
|
$output .= "function {$_funcName}(\$_smarty_tpl, \$_blockParentStack) {\n";
|
||||||
|
if (isset($_assign)) {
|
||||||
|
$output .= "ob_start();\n";
|
||||||
|
}
|
||||||
|
$output .= "?>\n";
|
||||||
$compiler->parser->current_buffer->append_subtree($compiler->parser,
|
$compiler->parser->current_buffer->append_subtree($compiler->parser,
|
||||||
new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
||||||
$output));
|
$output));
|
||||||
$compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
|
$compiler->parser->current_buffer->append_subtree($compiler->parser, $_functionCode);
|
||||||
$output = "<?php\n}\n";
|
$output = "<?php\n";
|
||||||
|
if (isset($_assign)) {
|
||||||
|
$output .= "\$_smarty_tpl->tpl_vars[{$_assign}] = new Smarty_Variable(ob_get_contents());\n";
|
||||||
|
}
|
||||||
|
$output .= "}\n";
|
||||||
$output .= "/* {/block '{$_name}'} */\n\n";
|
$output .= "/* {/block '{$_name}'} */\n\n";
|
||||||
$output .= "?>\n";
|
$output .= "?>\n";
|
||||||
$compiler->parser->current_buffer->append_subtree($compiler->parser,
|
$compiler->parser->current_buffer->append_subtree($compiler->parser,
|
||||||
new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
||||||
$output));
|
$output));
|
||||||
$compiler->blockOrFunctionCode .= $f =
|
$compiler->blockOrFunctionCode .= $compiler->parser->current_buffer->to_smarty_php($compiler->parser);
|
||||||
$compiler->parser->current_buffer->to_smarty_php($compiler->parser);
|
|
||||||
// nocache plugins must be copied
|
// nocache plugins must be copied
|
||||||
if (!empty($compiler->template->compiled->required_plugins['nocache'])) {
|
if (!empty($compiler->template->compiled->required_plugins['nocache'])) {
|
||||||
foreach ($compiler->template->compiled->required_plugins['nocache'] as $plugin => $tmp) {
|
foreach ($compiler->template->compiled->required_plugins['nocache'] as $plugin => $tmp) {
|
||||||
@@ -213,38 +250,27 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// restore old status
|
// restore old status
|
||||||
$compiler->template->compiled->has_nocache_code = $_has_nocache_code;
|
$compiler->template->compiled->has_nocache_code = $_has_nocache_code;
|
||||||
$compiler->tag_nocache = $compiler->nocache;
|
$compiler->tag_nocache = $compiler->nocache;
|
||||||
$compiler->nocache = $_nocache;
|
$compiler->nocache = $_nocache;
|
||||||
$compiler->parser->current_buffer = $_buffer;
|
$compiler->parser->current_buffer = $_buffer;
|
||||||
|
$output = "<?php \n";
|
||||||
$_parameter = $_attr;
|
if ($compiler->_cache['blockNesting'] == 1) {
|
||||||
foreach ($_parameter as $name => $stat) {
|
$output .= "\$_smarty_tpl->_inheritance->processBlock(\$_smarty_tpl, 0, {$compiler->_cache['blockName'][$compiler->_cache['blockNesting']]}, " .
|
||||||
if ($stat === false) {
|
var_export($_block, true) . ");\n";
|
||||||
unset($_parameter[$name]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (isset($compiler->callChildBlock[$compiler->blockTagNestingLevel])) {
|
|
||||||
$_parameter['callChildBlock'] = 'true';
|
|
||||||
unset($compiler->callChildBlock[$compiler->blockTagNestingLevel]);
|
|
||||||
}
|
|
||||||
$compiler->blockTagNestingLevel --;
|
|
||||||
// inner {block} or child template {block} must register block
|
|
||||||
if ($compiler->blockTagNestingLevel == 0 && $compiler->inheritanceChild) {
|
|
||||||
$_function = 'register';
|
|
||||||
} else {
|
} else {
|
||||||
$_function = 'call';
|
$output .= "\$_smarty_tpl->_inheritance->processBlock(\$_smarty_tpl, 0, {$compiler->_cache['blockName'][$compiler->_cache['blockNesting']]}, " .
|
||||||
|
var_export($_block, true) . ", \$_blockParentStack);\n";
|
||||||
|
|
||||||
}
|
}
|
||||||
$cm = $compiler->template->caching ? 'true' : 'false';
|
$output .= "?>\n";
|
||||||
$output =
|
$compiler->_cache['blockNesting'] --;
|
||||||
"<?php \n\$_smarty_tpl->_Block->{$_function}Block(\$_smarty_tpl, array('caching' => {$cm}, 'function' => '{$_funcNameCaching}'";
|
if ($compiler->_cache['blockNesting'] == 0) {
|
||||||
foreach ($_parameter as $name => $stat) {
|
unset($compiler->_cache['blockNesting']);
|
||||||
if ($stat !== false) {
|
|
||||||
$output .= ", '{$name}' => {$stat}";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
$output .= "));\n?>\n";
|
|
||||||
$compiler->has_code = true;
|
$compiler->has_code = true;
|
||||||
$compiler->suppressNocacheProcessing = true;
|
$compiler->suppressNocacheProcessing = true;
|
||||||
return $output;
|
return $output;
|
||||||
|
@@ -15,7 +15,7 @@
|
|||||||
* @package Smarty
|
* @package Smarty
|
||||||
* @subpackage Compiler
|
* @subpackage Compiler
|
||||||
*/
|
*/
|
||||||
class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase
|
class Smarty_Internal_Compile_Extends extends Smarty_Internal_Compile_Shared_Inheritance
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Attribute definition: Overwrites base class.
|
* Attribute definition: Overwrites base class.
|
||||||
@@ -25,6 +25,14 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase
|
|||||||
*/
|
*/
|
||||||
public $required_attributes = array('file');
|
public $required_attributes = array('file');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of names of optional attribute required by tag
|
||||||
|
* use array('_any') if there is no restriction of attributes names
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $optional_attributes = array('extends_resource');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attribute definition: Overwrites base class.
|
* Attribute definition: Overwrites base class.
|
||||||
*
|
*
|
||||||
@@ -34,7 +42,7 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase
|
|||||||
public $shorttag_order = array('file');
|
public $shorttag_order = array('file');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiles code for the {extends} tag
|
* Compiles code for the {extends} tag extends: resource
|
||||||
*
|
*
|
||||||
* @param array $args array with attributes from parser
|
* @param array $args array with attributes from parser
|
||||||
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
|
* @param \Smarty_Internal_TemplateCompilerBase $compiler compiler object
|
||||||
@@ -53,11 +61,74 @@ class Smarty_Internal_Compile_Extends extends Smarty_Internal_CompileBase
|
|||||||
if (strpos($_attr['file'], '$_tmp') !== false) {
|
if (strpos($_attr['file'], '$_tmp') !== false) {
|
||||||
$compiler->trigger_template_error('illegal value for file attribute', $compiler->parser->lex->line - 1);
|
$compiler->trigger_template_error('illegal value for file attribute', $compiler->parser->lex->line - 1);
|
||||||
}
|
}
|
||||||
// save template name
|
// add code to initialize inheritance
|
||||||
$compiler->extendsFileName = $_attr['file'];
|
$this->registerInit($compiler, true);
|
||||||
// process {block} in child template mode
|
$file = trim($_attr['file'], '\'"');
|
||||||
$compiler->inheritanceChild = true;
|
if (strlen($file) > 8 && substr($file, 0, 8) == 'extends:') {
|
||||||
|
// generate code for each template
|
||||||
|
$files = array_reverse(explode('|', substr($file, 8)));
|
||||||
|
$i = 0;
|
||||||
|
foreach ($files as $file) {
|
||||||
|
if ($file[0] == '"') {
|
||||||
|
$file = trim($file, '".');
|
||||||
|
} else {
|
||||||
|
$file = "'{$file}'";
|
||||||
|
}
|
||||||
|
$i ++;
|
||||||
|
if ($i == count($files) && isset($_attr['extends_resource'])) {
|
||||||
|
$this->compileEndChild($compiler);
|
||||||
|
}
|
||||||
|
$this->compileInclude($compiler, $file);
|
||||||
|
}
|
||||||
|
if (!isset($_attr['extends_resource'])) {
|
||||||
|
$this->compileEndChild($compiler);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$this->compileEndChild($compiler);
|
||||||
|
$this->compileInclude($compiler, $_attr['file']);
|
||||||
|
}
|
||||||
$compiler->has_code = false;
|
$compiler->has_code = false;
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add code for inheritance endChild() method to end of template
|
||||||
|
*
|
||||||
|
* @param \Smarty_Internal_TemplateCompilerBase $compiler
|
||||||
|
*/
|
||||||
|
private function compileEndChild(Smarty_Internal_TemplateCompilerBase $compiler)
|
||||||
|
{
|
||||||
|
$compiler->parser->template_postfix[] = new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
||||||
|
"<?php \$_smarty_tpl->_inheritance->endChild(\$_smarty_tpl);\n?>\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add code for including subtemplate to end of template
|
||||||
|
*
|
||||||
|
* @param \Smarty_Internal_TemplateCompilerBase $compiler
|
||||||
|
* @param string $file subtemplate name
|
||||||
|
*/
|
||||||
|
private function compileInclude(Smarty_Internal_TemplateCompilerBase $compiler, $file)
|
||||||
|
{
|
||||||
|
$compiler->parser->template_postfix[] = new Smarty_Internal_ParseTree_Tag($compiler->parser,
|
||||||
|
$compiler->compileTag('include',
|
||||||
|
array($file,
|
||||||
|
array('scope' => 'parent'))));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create source code for {extends} from source components array
|
||||||
|
*
|
||||||
|
* @param []\Smarty_Internal_Template_Source $components
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public static function extendsSourceArrayCode($components)
|
||||||
|
{
|
||||||
|
$resources = array();
|
||||||
|
foreach ($components as $source) {
|
||||||
|
$resources[] = $source->resource;
|
||||||
|
}
|
||||||
|
return '{extends file=\'extends:' . join('|', $resources) . '\' extends_resource=true}';
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -98,9 +98,6 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
|||||||
} else {
|
} else {
|
||||||
$variable_template = true;
|
$variable_template = true;
|
||||||
}
|
}
|
||||||
if ($compiler->inheritanceForceChild) {
|
|
||||||
$hashResourceName .= '-child';
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_attr['assign'])) {
|
if (isset($_attr['assign'])) {
|
||||||
// output will be stored in a smarty variable instead of being displayed
|
// output will be stored in a smarty variable instead of being displayed
|
||||||
@@ -297,19 +294,22 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
|||||||
*
|
*
|
||||||
* @return bool
|
* @return bool
|
||||||
*/
|
*/
|
||||||
public function compileInlineTemplate(Smarty_Internal_SmartyTemplateCompiler $compiler, $fullResourceName, $_caching, $hashResourceName, $t_hash, $c_id)
|
public function compileInlineTemplate(Smarty_Internal_SmartyTemplateCompiler $compiler, $fullResourceName,
|
||||||
|
$_caching, $hashResourceName, $t_hash, $c_id)
|
||||||
{
|
{
|
||||||
$compiler->smarty->allow_ambiguous_resources = true;
|
$compiler->smarty->allow_ambiguous_resources = true;
|
||||||
/* @var Smarty_Internal_Template $tpl */
|
/* @var Smarty_Internal_Template $tpl */
|
||||||
$tpl = new $compiler->smarty->template_class (trim($fullResourceName, "'"), $compiler->smarty, $compiler->template,
|
$tpl =
|
||||||
$compiler->template->cache_id, $c_id, $_caching);
|
new $compiler->smarty->template_class (trim($fullResourceName, "'"), $compiler->smarty, $compiler->template,
|
||||||
$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['uid'] = $tpl->source->uid;
|
$compiler->template->cache_id, $c_id, $_caching);
|
||||||
if (!($tpl->source->handler->uncompiled) && $tpl->source->exists) {
|
if (!($tpl->source->handler->uncompiled) && $tpl->source->exists) {
|
||||||
|
$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['uid'] = $tpl->source->uid;
|
||||||
|
if (isset($compiler->template->_inheritance)) {
|
||||||
|
$tpl->_inheritance = clone $compiler->template->_inheritance;
|
||||||
|
}
|
||||||
$tpl->compiled = new Smarty_Template_Compiled();
|
$tpl->compiled = new Smarty_Template_Compiled();
|
||||||
$tpl->compiled->nocache_hash = $compiler->parent_compiler->template->compiled->nocache_hash;
|
$tpl->compiled->nocache_hash = $compiler->parent_compiler->template->compiled->nocache_hash;
|
||||||
$tpl->loadCompiler();
|
$tpl->loadCompiler();
|
||||||
$tpl->compiler->inheritanceChild = $tpl->compiler->inheritanceForceChild = $compiler->inheritanceForceChild;
|
|
||||||
$tpl->compiler->inheritance = $compiler->inheritance;
|
|
||||||
// save unique function name
|
// save unique function name
|
||||||
$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['func'] =
|
$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['func'] =
|
||||||
$tpl->compiled->unifunc = 'content_' . str_replace(array('.', ','), '_', uniqid('', true));
|
$tpl->compiled->unifunc = 'content_' . str_replace(array('.', ','), '_', uniqid('', true));
|
||||||
@@ -328,13 +328,12 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
|||||||
$compiled_code .= "<?php\n\n";
|
$compiled_code .= "<?php\n\n";
|
||||||
$compiled_code .= "/* End inline template \"{$tpl->source->type}:{$tpl->source->name}\" =============================*/\n";
|
$compiled_code .= "/* End inline template \"{$tpl->source->type}:{$tpl->source->name}\" =============================*/\n";
|
||||||
$compiled_code .= "?>";
|
$compiled_code .= "?>";
|
||||||
$compiler->inheritanceParentIsChild = $tpl->compiler->inheritanceChild;
|
|
||||||
$compiler->inheritance = $tpl->compiler->inheritance;
|
|
||||||
unset($tpl->compiler);
|
unset($tpl->compiler);
|
||||||
if ($tpl->compiled->has_nocache_code) {
|
if ($tpl->compiled->has_nocache_code) {
|
||||||
// replace nocache_hash
|
// replace nocache_hash
|
||||||
$compiled_code = str_replace("{$tpl->compiled->nocache_hash}", $compiler->template->compiled->nocache_hash,
|
$compiled_code =
|
||||||
$compiled_code);
|
str_replace("{$tpl->compiled->nocache_hash}", $compiler->template->compiled->nocache_hash,
|
||||||
|
$compiled_code);
|
||||||
$compiler->template->compiled->has_nocache_code = true;
|
$compiler->template->compiled->has_nocache_code = true;
|
||||||
}
|
}
|
||||||
$compiler->parent_compiler->mergedSubTemplatesCode[$tpl->compiled->unifunc] = $compiled_code;
|
$compiler->parent_compiler->mergedSubTemplatesCode[$tpl->compiled->unifunc] = $compiled_code;
|
||||||
|
@@ -0,0 +1,46 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Smarty Internal Plugin Compile Shared Inheritance
|
||||||
|
* Shared methods for {extends} and {block} tags
|
||||||
|
*
|
||||||
|
* @package Smarty
|
||||||
|
* @subpackage Compiler
|
||||||
|
* @author Uwe Tews
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty Internal Plugin Compile Shared Inheritance Class
|
||||||
|
*
|
||||||
|
* @package Smarty
|
||||||
|
* @subpackage Compiler
|
||||||
|
*/
|
||||||
|
class Smarty_Internal_Compile_Shared_Inheritance extends Smarty_Internal_CompileBase
|
||||||
|
{
|
||||||
|
/**
|
||||||
|
* Register post compile callback to compile inheritance initialization code
|
||||||
|
*
|
||||||
|
* @param \Smarty_Internal_TemplateCompilerBase $compiler
|
||||||
|
* @param bool|false $initChildSequence if true force child template
|
||||||
|
*/
|
||||||
|
public function registerInit(Smarty_Internal_TemplateCompilerBase $compiler, $initChildSequence = false)
|
||||||
|
{
|
||||||
|
if ($initChildSequence || !isset($compiler->_cache['inheritanceInit'])) {
|
||||||
|
$compiler->registerPostCompileCallback(array('Smarty_Internal_Compile_Shared_Inheritance', 'postCompile'),
|
||||||
|
array($initChildSequence), 'inheritanceInit', $initChildSequence);
|
||||||
|
|
||||||
|
$compiler->_cache['inheritanceInit'] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compile inheritance initialization code as prefix
|
||||||
|
*
|
||||||
|
* @param \Smarty_Internal_TemplateCompilerBase $compiler
|
||||||
|
* @param bool|false $initChildSequence if true force child template
|
||||||
|
*/
|
||||||
|
static function postCompile(Smarty_Internal_TemplateCompilerBase $compiler, $initChildSequence = false)
|
||||||
|
{
|
||||||
|
$compiler->prefixCompiledCode .= "<?php \$_smarty_tpl->_inheritance->init(\$_smarty_tpl, " .
|
||||||
|
var_export($initChildSequence, true) . ");\n?>\n";
|
||||||
|
}
|
||||||
|
}
|
@@ -1,98 +0,0 @@
|
|||||||
<?php
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Runtime Method _callBlock, _callParentBlock, _callChildBlock, _registerBlock
|
|
||||||
*
|
|
||||||
* @package Smarty
|
|
||||||
* @subpackage PluginsInternal
|
|
||||||
* @author Uwe Tews
|
|
||||||
*
|
|
||||||
**/
|
|
||||||
class Smarty_Internal_Runtime_Block
|
|
||||||
{
|
|
||||||
|
|
||||||
public $inheritanceBlocks = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call inheritance {block} tag
|
|
||||||
*
|
|
||||||
* @param \Smarty_Internal_Template $callerTpl template object of caller
|
|
||||||
* @param array $block block parameter
|
|
||||||
*/
|
|
||||||
public function callBlock(Smarty_Internal_Template $callerTpl, $block)
|
|
||||||
{
|
|
||||||
$function = $block['function'];
|
|
||||||
$level = isset($block['level']) ? $block['level'] : 0;
|
|
||||||
// find to level child block
|
|
||||||
while (!isset($block['callChildBlock']) &&
|
|
||||||
isset($this->inheritanceBlocks[$block['name']][$level])) {
|
|
||||||
$block = $this->inheritanceBlocks[$block['name']][$level];
|
|
||||||
$block['level'] = $level;
|
|
||||||
$level ++;
|
|
||||||
}
|
|
||||||
// ignore hidden block
|
|
||||||
if (isset($block['hide'])) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// root block function for possible parent block call
|
|
||||||
$block['root'] = $function;
|
|
||||||
if (isset($block['append'])) {
|
|
||||||
$this->callParentBlock($callerTpl, $block);
|
|
||||||
}
|
|
||||||
$block['function']($callerTpl, $block);
|
|
||||||
if (isset($block['prepend'])) {
|
|
||||||
$this->callParentBlock($callerTpl, $block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call inheritance parent {block} tag
|
|
||||||
*
|
|
||||||
* @param \Smarty_Internal_Template $callerTpl template object of caller
|
|
||||||
* @param array $block block parameter
|
|
||||||
*/
|
|
||||||
public function callParentBlock(Smarty_Internal_Template $callerTpl, $block)
|
|
||||||
{
|
|
||||||
$level = isset($block['level']) ? $block['level'] : 0;
|
|
||||||
if (isset($this->inheritanceBlocks[$block['name']][$level - 1])) {
|
|
||||||
// call registered parent
|
|
||||||
$parent = $this->inheritanceBlocks[$block['name']][$level - 1];
|
|
||||||
$parent['root'] = $block['root'];
|
|
||||||
$parent['function']($callerTpl, $parent);
|
|
||||||
} else {
|
|
||||||
// default to root block
|
|
||||||
$block['root']($callerTpl, $block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Call inheritance child {block} tag
|
|
||||||
*
|
|
||||||
* @param \Smarty_Internal_Template $callerTpl template object of caller
|
|
||||||
* @param array $block block parameter
|
|
||||||
*/
|
|
||||||
public function callChildBlock(Smarty_Internal_Template $callerTpl, $block)
|
|
||||||
{
|
|
||||||
$level = isset($block['level']) ? $block['level'] : - 1;
|
|
||||||
if (isset($this->inheritanceBlocks[$block['name']][$level + 1])) {
|
|
||||||
$child = $this->inheritanceBlocks[$block['name']][$level + 1];
|
|
||||||
$child['level'] = $level + 1;
|
|
||||||
$child['function']($callerTpl, $child);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Register inheritance {block} tag
|
|
||||||
*
|
|
||||||
* @param \Smarty_Internal_Template $callerTpl template object of caller
|
|
||||||
* @param array $block block parameter
|
|
||||||
*/
|
|
||||||
public function registerBlock(Smarty_Internal_Template $callerTpl, $block)
|
|
||||||
{
|
|
||||||
if (!isset($this->inheritanceBlocks[$block['name']])) {
|
|
||||||
$this->inheritanceBlocks[$block['name']][0] = $block;
|
|
||||||
} else {
|
|
||||||
array_unshift($this->inheritanceBlocks[$block['name']], $block);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
208
libs/sysplugins/smarty_internal_runtime_inheritance.php
Normal file
208
libs/sysplugins/smarty_internal_runtime_inheritance.php
Normal file
@@ -0,0 +1,208 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Runtime Method callBlock,callParentBlock, callChildBlock, registerBlock
|
||||||
|
*
|
||||||
|
* @package Smarty
|
||||||
|
* @subpackage PluginsInternal
|
||||||
|
* @author Uwe Tews
|
||||||
|
*
|
||||||
|
**/
|
||||||
|
class Smarty_Internal_Runtime_Inheritance
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* State machine
|
||||||
|
* - 0 idle next extends will create a new inheritance tree
|
||||||
|
* - 1 processing child template
|
||||||
|
* - 2 wait for next inheritance template
|
||||||
|
* - 3 assume parent template, if child will loaded goto state 1
|
||||||
|
* a call to a sub template resets the state to 0
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $state = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of block parameter of known {block} tags
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $blockParameter = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* inheritance template nesting level
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $inheritanceLevel = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* inheritance template index
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $tplIndex = - 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of compiled template file path
|
||||||
|
* - key template index
|
||||||
|
* only used when caching is enabled
|
||||||
|
*
|
||||||
|
* @var []string
|
||||||
|
*/
|
||||||
|
public $compiledFilePath = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Current {block} nesting level
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $blockNesting = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initialize inheritance
|
||||||
|
*
|
||||||
|
* @param \Smarty_Internal_Template $tpl template object of caller
|
||||||
|
* @param bool $initChild if true init for child template
|
||||||
|
* @param array $blockNames outer level block name
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function init(Smarty_Internal_Template $tpl, $initChild, $blockNames = array())
|
||||||
|
{
|
||||||
|
// if template was from an inner block or template is a parent template create new inheritance root
|
||||||
|
if ($initChild && ($this->blockNesting || $this->state == 3)) {
|
||||||
|
$tpl->_inheritance = new Smarty_Internal_Runtime_Inheritance();
|
||||||
|
$tpl->_inheritance->init($tpl, $initChild, $blockNames);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// start of child sub template(s)
|
||||||
|
if ($initChild) {
|
||||||
|
$this->state = 1;
|
||||||
|
if (!$this->inheritanceLevel) {
|
||||||
|
//grab any output of child templates
|
||||||
|
ob_start();
|
||||||
|
}
|
||||||
|
$this->inheritanceLevel ++;
|
||||||
|
}
|
||||||
|
// in parent state {include} will not increment template index
|
||||||
|
if ($this->state != 3) {
|
||||||
|
$this->tplIndex ++;
|
||||||
|
}
|
||||||
|
// if state was waiting for parent change state to parent
|
||||||
|
if ($this->state == 2) {
|
||||||
|
$this->state = 3;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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 template object of caller
|
||||||
|
*/
|
||||||
|
public function endChild(Smarty_Internal_Template $tpl)
|
||||||
|
{
|
||||||
|
$this->inheritanceLevel --;
|
||||||
|
if (!$this->inheritanceLevel) {
|
||||||
|
ob_end_clean();
|
||||||
|
$this->state = 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process inheritance {block} tag
|
||||||
|
*
|
||||||
|
* $type 0 = {block}:
|
||||||
|
* - search in inheritance template hierarchy for child blocks
|
||||||
|
* if found call it, otherwise call current block
|
||||||
|
* - ignored for outer level blocks in child templates
|
||||||
|
*
|
||||||
|
* $type 1 = {$smarty.block.child}:
|
||||||
|
* - search in inheritance template hierarchy for child blocks
|
||||||
|
* if found call it, otherwise ignore
|
||||||
|
*
|
||||||
|
* $type 2 = {$smarty.block.parent}:
|
||||||
|
* - get block id from parent stack and call parent block
|
||||||
|
*
|
||||||
|
* @param \Smarty_Internal_Template $tpl template object of caller
|
||||||
|
* @param int $type call type see above
|
||||||
|
* @param string $name block name
|
||||||
|
* @param array $block block parameter
|
||||||
|
* @param array $callStack call stack with block parameters
|
||||||
|
*
|
||||||
|
* @throws \SmartyException
|
||||||
|
*/
|
||||||
|
public function processBlock(Smarty_Internal_Template $tpl, $type = 0, $name, $block, $callStack = array())
|
||||||
|
{
|
||||||
|
if (!isset($this->blockParameter[$name])) {
|
||||||
|
$this->blockParameter[$name] = array();
|
||||||
|
}
|
||||||
|
if ($this->state == 1) {
|
||||||
|
$block[2] = count($this->blockParameter[$name]);
|
||||||
|
$block[3] = $this->tplIndex;
|
||||||
|
$this->blockParameter[$name][] = $block;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if ($type == 3) {
|
||||||
|
if (!empty($callStack)) {
|
||||||
|
array_shift($callStack);
|
||||||
|
if (empty($callStack)) {
|
||||||
|
throw new SmartyException("inheritance: tag {\$smarty.block.parent} used in parent template block '{$name}'");
|
||||||
|
}
|
||||||
|
$block = array_shift($callStack);
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$blockParameter = &$this->blockParameter[$name];
|
||||||
|
if ($type == 0) {
|
||||||
|
$index = $block[2] = count($blockParameter);
|
||||||
|
$block[3] = $this->tplIndex;
|
||||||
|
$callStack = array(&$block);
|
||||||
|
} elseif ($type == 1) {
|
||||||
|
$block[3] = $callStack[0][3];
|
||||||
|
$index = 0;
|
||||||
|
for ($i = 0; $i < count($blockParameter); $i ++) {
|
||||||
|
if ($blockParameter[$i][3] <= $block[3]) {
|
||||||
|
$index = $blockParameter[$i][2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$block[2] = $index;
|
||||||
|
$callStack = array(&$block);
|
||||||
|
} else {
|
||||||
|
$index = $callStack[0][2];
|
||||||
|
if ($index == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$callStack = $block = array(1 => false);
|
||||||
|
}
|
||||||
|
$index --;
|
||||||
|
// find lowest level child block
|
||||||
|
while ($index >= 0 && ($type || !$block[1])) {
|
||||||
|
$block = &$blockParameter[$index];
|
||||||
|
array_unshift($callStack, $block);
|
||||||
|
if ($block[1]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
$index --;
|
||||||
|
}
|
||||||
|
if (isset($block['hide']) && $index <= 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$this->blockNesting ++;
|
||||||
|
if (isset($block['append'])) {
|
||||||
|
$this->processBlock($tpl, 3, $name, null, $callStack);
|
||||||
|
}
|
||||||
|
if (isset($block[6])) {
|
||||||
|
$block[6]($tpl, $callStack);
|
||||||
|
} else {
|
||||||
|
$block[0]($tpl, $callStack);
|
||||||
|
}
|
||||||
|
if (isset($block['prepend'])) {
|
||||||
|
$this->processBlock($tpl, 3, $name, null, $callStack);
|
||||||
|
}
|
||||||
|
$this->blockNesting --;
|
||||||
|
}
|
||||||
|
}
|
@@ -17,6 +17,7 @@
|
|||||||
* @property Smarty_Template_Source|Smarty_Template_Config $source
|
* @property Smarty_Template_Source|Smarty_Template_Config $source
|
||||||
* @property Smarty_Template_Compiled $compiled
|
* @property Smarty_Template_Compiled $compiled
|
||||||
* @property Smarty_Template_Cached $cached
|
* @property Smarty_Template_Cached $cached
|
||||||
|
* @property Smarty_Internal_Runtime_Inheritance $_inheritance
|
||||||
* @method bool mustCompile()
|
* @method bool mustCompile()
|
||||||
*/
|
*/
|
||||||
class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
||||||
@@ -314,10 +315,10 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
}
|
}
|
||||||
$tpl->tpl_function = $this->tpl_function;
|
$tpl->tpl_function = $this->tpl_function;
|
||||||
// copy inheritance object?
|
// copy inheritance object?
|
||||||
if (isset($this->_Block)) {
|
if (isset($this->_inheritance)) {
|
||||||
$tpl->_Block = $this->_Block;
|
$tpl->_inheritance = $this->_inheritance;
|
||||||
} else {
|
} else {
|
||||||
unset($tpl->_Block);
|
unset($tpl->_inheritance);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
$tpl = clone $this;
|
$tpl = clone $this;
|
||||||
@@ -692,8 +693,8 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
{
|
{
|
||||||
// object properties of runtime template extensions will start with '_'
|
// object properties of runtime template extensions will start with '_'
|
||||||
if ($property_name[0] == '_') {
|
if ($property_name[0] == '_') {
|
||||||
$property_name[1] = chr(ord($property_name[1]) & 0xDF);
|
|
||||||
$class = 'Smarty_Internal_Runtime' . $property_name;
|
$class = 'Smarty_Internal_Runtime' . $property_name;
|
||||||
|
$class[24] = chr(ord($class[24]) & 0xDF);
|
||||||
if (class_exists($class)) {
|
if (class_exists($class)) {
|
||||||
return $this->$property_name = new $class();
|
return $this->$property_name = new $class();
|
||||||
}
|
}
|
||||||
|
@@ -14,6 +14,11 @@
|
|||||||
*
|
*
|
||||||
* @package Smarty
|
* @package Smarty
|
||||||
* @subpackage Compiler
|
* @subpackage Compiler
|
||||||
|
*
|
||||||
|
* @property Smarty_Internal_SmartyTemplateCompiler $prefixCompiledCode = ''
|
||||||
|
* @property Smarty_Internal_SmartyTemplateCompiler $postfixCompiledCode = ''
|
||||||
|
* @method Smarty_Internal_SmartyTemplateCompiler registerPostCompileCallback($callback, $parameter = array(), $key = null, $replace = false)
|
||||||
|
* @method Smarty_Internal_SmartyTemplateCompiler unregisterPostCompileCallback($key)
|
||||||
*/
|
*/
|
||||||
abstract class Smarty_Internal_TemplateCompilerBase
|
abstract class Smarty_Internal_TemplateCompilerBase
|
||||||
{
|
{
|
||||||
@@ -88,55 +93,6 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
*/
|
*/
|
||||||
public $templateProperties = array();
|
public $templateProperties = array();
|
||||||
|
|
||||||
/**
|
|
||||||
* sources which must be compiled
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
public $sources = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* flag when compiling inheritance template
|
|
||||||
*
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
public $inheritance = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* flag when compiling inheritance child template
|
|
||||||
*
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
public $inheritanceChild = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Force all subtemplate calls to be inheritance childs
|
|
||||||
*
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
public $inheritanceForceChild = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag if compiled parent template is child of other parent
|
|
||||||
*
|
|
||||||
* @var bool
|
|
||||||
*/
|
|
||||||
public $inheritanceParentIsChild = false;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* uid of templates called by {extends} for recursion check
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
public $extends_uid = array();
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Template name of {extends} tag
|
|
||||||
*
|
|
||||||
* @var null|string
|
|
||||||
*/
|
|
||||||
public $extendsFileName = null;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* source line offset for error messages
|
* source line offset for error messages
|
||||||
*
|
*
|
||||||
@@ -305,20 +261,6 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
*/
|
*/
|
||||||
public $loopNesting = 0;
|
public $loopNesting = 0;
|
||||||
|
|
||||||
/**
|
|
||||||
* nesting level of block tags
|
|
||||||
*
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
public $blockTagNestingLevel = 0;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Flag if {$smarty.block.child} was called at $blockTagNestingLevel
|
|
||||||
*
|
|
||||||
* @var array
|
|
||||||
*/
|
|
||||||
public $callChildBlock = array();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Strip preg pattern
|
* Strip preg pattern
|
||||||
*
|
*
|
||||||
@@ -333,6 +275,13 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
*/
|
*/
|
||||||
public $plugin_search_order = array('function', 'block', 'compiler', 'class');
|
public $plugin_search_order = array('function', 'block', 'compiler', 'class');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* General storage area for tag compiler plugins
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $_cache = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* method to compile a Smarty template
|
* method to compile a Smarty template
|
||||||
*
|
*
|
||||||
@@ -345,9 +294,12 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Initialize compiler
|
* Initialize compiler
|
||||||
|
*
|
||||||
|
* @param Smarty $smarty global instance
|
||||||
*/
|
*/
|
||||||
public function __construct()
|
public function __construct(Smarty $smarty)
|
||||||
{
|
{
|
||||||
|
$this->smarty = $smarty;
|
||||||
$this->nocache_hash = str_replace(array('.', ','), '_', uniqid(rand(), true));
|
$this->nocache_hash = str_replace(array('.', ','), '_', uniqid(rand(), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -424,13 +376,13 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
// get template source
|
// get template source
|
||||||
if (!empty($this->template->source->components)) {
|
if (!empty($this->template->source->components)) {
|
||||||
// we have array of inheritance templates by extends: resource
|
// we have array of inheritance templates by extends: resource
|
||||||
$this->sources = array_reverse($this->template->source->components);
|
// generate corresponding source code sequence
|
||||||
$_content = '';
|
$_content =
|
||||||
|
Smarty_Internal_Compile_Extends::extendsSourceArrayCode($this->template->source->components);
|
||||||
} else {
|
} else {
|
||||||
// get template source
|
// get template source
|
||||||
$_content = $this->template->source->getContent();
|
$_content = $this->template->source->getContent();
|
||||||
}
|
}
|
||||||
|
|
||||||
$_compiled_code = $this->postFilter($this->doCompile($this->preFilter($_content), true));
|
$_compiled_code = $this->postFilter($this->doCompile($this->preFilter($_content), true));
|
||||||
}
|
}
|
||||||
catch (Exception $e) {
|
catch (Exception $e) {
|
||||||
@@ -494,64 +446,6 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Add code to call parent template on inheritance child templates
|
|
||||||
*
|
|
||||||
* @param $parser
|
|
||||||
*
|
|
||||||
* @throws \SmartyException
|
|
||||||
*/
|
|
||||||
public function processInheritance($parser)
|
|
||||||
{
|
|
||||||
if (isset($this->extendsFileName)) {
|
|
||||||
// child did use {extends}
|
|
||||||
$name = $this->extendsFileName;
|
|
||||||
$this->extendsFileName = null;
|
|
||||||
if (!$this->inheritanceForceChild && !$this->inheritance) {
|
|
||||||
// drop any output of child templates
|
|
||||||
array_unshift($parser->current_buffer->subtrees, new Smarty_Internal_ParseTree_Tag($parser,
|
|
||||||
"<?php ob_start();\n\$_smarty_tpl->_Block = new Smarty_Internal_Runtime_Block();?>\n"));
|
|
||||||
$this->inheritance = true;
|
|
||||||
}
|
|
||||||
$include = new Smarty_Internal_ParseTree_Tag($parser, $this->compileTag('include', array($name,
|
|
||||||
array('scope' => 'parent'),
|
|
||||||
array('inline' => true))));
|
|
||||||
if (!$this->inheritanceForceChild && !$this->inheritanceParentIsChild) {
|
|
||||||
$parser->current_buffer->append_subtree($parser, new Smarty_Internal_ParseTree_Tag($parser,
|
|
||||||
"<?php ob_end_clean();?>\n"));
|
|
||||||
$this->inheritance = false;
|
|
||||||
}
|
|
||||||
$this->inheritanceParentIsChild = false;
|
|
||||||
$parser->current_buffer->append_subtree($parser, $include);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// template list of extends: resource ?
|
|
||||||
if (!empty($this->sources)) {
|
|
||||||
if (!$this->inheritanceForceChild) {
|
|
||||||
// drop any output of child templates
|
|
||||||
$parser->current_buffer->append_subtree($parser, new Smarty_Internal_ParseTree_Tag($parser,
|
|
||||||
"<?php ob_start();\n\$_smarty_tpl->_Block = new Smarty_Internal_Runtime_Block();?>\n"));
|
|
||||||
}
|
|
||||||
while (!empty($this->sources)) {
|
|
||||||
$source = array_shift($this->sources);
|
|
||||||
if (!$this->inheritanceForceChild && empty($this->sources)) {
|
|
||||||
// drop any output of child templates
|
|
||||||
$parser->current_buffer->append_subtree($parser, new Smarty_Internal_ParseTree_Tag($parser,
|
|
||||||
"<?php ob_end_clean();?>\n"));
|
|
||||||
}
|
|
||||||
$forceChild = $this->inheritanceForceChild;
|
|
||||||
$this->inheritanceForceChild = $this->inheritanceForceChild || !empty($this->sources);
|
|
||||||
$parser->current_buffer->append_subtree($parser, new Smarty_Internal_ParseTree_Tag($parser,
|
|
||||||
$this->compileTag('include',
|
|
||||||
array("'{$source->resource}'",
|
|
||||||
array('scope' => 'parent'),
|
|
||||||
array('inline' => true)))));
|
|
||||||
// restore value
|
|
||||||
$this->inheritanceForceChild = $forceChild;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compile Tag
|
* Compile Tag
|
||||||
* This is a call back from the lexer/parser
|
* This is a call back from the lexer/parser
|
||||||
|
Reference in New Issue
Block a user