mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-03 01:44:26 +02:00
Moved handling of smarty.block.* to special compilers, because they aren't real tags. Organized tag-stack handling in compiler, unified nocache handling in compiler.
This commit is contained in:
@@ -5,6 +5,7 @@
|
||||
*/
|
||||
namespace Smarty\Compile;
|
||||
|
||||
use Smarty\Compiler\Template;
|
||||
use Smarty\Data;
|
||||
use Smarty\Exception;
|
||||
|
||||
@@ -49,20 +50,6 @@ abstract class Base implements CompilerInterface {
|
||||
*/
|
||||
protected $cacheable = true;
|
||||
|
||||
/**
|
||||
* Mapping array for boolean option value
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $optionMap = [1 => true, 0 => false, 'true' => true, 'false' => false];
|
||||
|
||||
/**
|
||||
* Mapping array with attributes as key
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $mapCache = [];
|
||||
|
||||
public function isCacheable(): bool {
|
||||
return $this->cacheable;
|
||||
}
|
||||
@@ -96,14 +83,12 @@ abstract class Base implements CompilerInterface {
|
||||
*/
|
||||
protected function getAttributes($compiler, $attributes) {
|
||||
$_indexed_attr = [];
|
||||
if (!isset($this->mapCache['option'])) {
|
||||
$this->mapCache['option'] = array_fill_keys($this->option_flags, true);
|
||||
}
|
||||
$options = array_fill_keys($this->option_flags, true);
|
||||
foreach ($attributes as $key => $mixed) {
|
||||
// shorthand ?
|
||||
if (!is_array($mixed)) {
|
||||
// option flag ?
|
||||
if (isset($this->mapCache['option'][trim($mixed, '\'"')])) {
|
||||
// options flag ?
|
||||
if (isset($options[trim($mixed, '\'"')])) {
|
||||
$_indexed_attr[trim($mixed, '\'"')] = true;
|
||||
// shorthand attribute ?
|
||||
} elseif (isset($this->shorttag_order[$key])) {
|
||||
@@ -115,20 +100,24 @@ abstract class Base implements CompilerInterface {
|
||||
// named attribute
|
||||
} else {
|
||||
foreach ($mixed as $k => $v) {
|
||||
// option flag?
|
||||
if (isset($this->mapCache['option'][$k])) {
|
||||
// options flag?
|
||||
if (isset($options[$k])) {
|
||||
if (is_bool($v)) {
|
||||
$_indexed_attr[$k] = $v;
|
||||
} else {
|
||||
if (is_string($v)) {
|
||||
$v = trim($v, '\'" ');
|
||||
}
|
||||
if (isset($this->optionMap[$v])) {
|
||||
$_indexed_attr[$k] = $this->optionMap[$v];
|
||||
|
||||
// Mapping array for boolean option value
|
||||
static $optionMap = [1 => true, 0 => false, 'true' => true, 'false' => false];
|
||||
|
||||
if (isset($optionMap[$v])) {
|
||||
$_indexed_attr[$k] = $optionMap[$v];
|
||||
} else {
|
||||
$compiler->trigger_template_error(
|
||||
"illegal value '" . var_export($v, true) .
|
||||
"' for option flag '{$k}'",
|
||||
"' for options flag '{$k}'",
|
||||
null,
|
||||
true
|
||||
);
|
||||
@@ -149,32 +138,27 @@ abstract class Base implements CompilerInterface {
|
||||
}
|
||||
// check for not allowed attributes
|
||||
if ($this->optional_attributes !== ['_any']) {
|
||||
if (!isset($this->mapCache['all'])) {
|
||||
$this->mapCache['all'] =
|
||||
array_fill_keys(
|
||||
array_merge(
|
||||
$this->required_attributes,
|
||||
$this->optional_attributes,
|
||||
$this->option_flags
|
||||
),
|
||||
true
|
||||
);
|
||||
}
|
||||
$allowedAttributes = array_fill_keys(
|
||||
array_merge(
|
||||
$this->required_attributes,
|
||||
$this->optional_attributes,
|
||||
$this->option_flags
|
||||
),
|
||||
true
|
||||
);
|
||||
foreach ($_indexed_attr as $key => $dummy) {
|
||||
if (!isset($this->mapCache['all'][$key]) && $key !== 0) {
|
||||
if (!isset($allowedAttributes[$key]) && $key !== 0) {
|
||||
$compiler->trigger_template_error("unexpected '{$key}' attribute", null, true);
|
||||
}
|
||||
}
|
||||
}
|
||||
// default 'false' for all option flags not set
|
||||
// default 'false' for all options flags not set
|
||||
foreach ($this->option_flags as $flag) {
|
||||
if (!isset($_indexed_attr[$flag])) {
|
||||
$_indexed_attr[$flag] = false;
|
||||
}
|
||||
}
|
||||
if (isset($_indexed_attr['nocache']) && $_indexed_attr['nocache']) {
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
|
||||
return $_indexed_attr;
|
||||
}
|
||||
|
||||
@@ -182,44 +166,25 @@ abstract class Base implements CompilerInterface {
|
||||
* Push opening tag name on stack
|
||||
* Optionally additional data can be saved on stack
|
||||
*
|
||||
* @param object $compiler compiler object
|
||||
* @param Template $compiler compiler object
|
||||
* @param string $openTag the opening tag's name
|
||||
* @param mixed $data optional data saved
|
||||
*/
|
||||
protected function openTag($compiler, $openTag, $data = null) {
|
||||
array_push($compiler->_tag_stack, [$openTag, $data]);
|
||||
protected function openTag(Template $compiler, $openTag, $data = null) {
|
||||
$compiler->openTag($openTag, $data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop closing tag
|
||||
* Raise an error if this stack-top doesn't match with expected opening tags
|
||||
*
|
||||
* @param object $compiler compiler object
|
||||
* @param Template $compiler compiler object
|
||||
* @param array|string $expectedTag the expected opening tag names
|
||||
*
|
||||
* @return mixed any type the opening tag's name or saved data
|
||||
*/
|
||||
protected function closeTag($compiler, $expectedTag) {
|
||||
if (count($compiler->_tag_stack) > 0) {
|
||||
// get stacked info
|
||||
[$_openTag, $_data] = array_pop($compiler->_tag_stack);
|
||||
// open tag must match with the expected ones
|
||||
if (in_array($_openTag, (array)$expectedTag)) {
|
||||
if (is_null($_data)) {
|
||||
// return opening tag
|
||||
return $_openTag;
|
||||
} else {
|
||||
// return restored data
|
||||
return $_data;
|
||||
}
|
||||
}
|
||||
// wrong nesting of tags
|
||||
$compiler->trigger_template_error("unclosed '" . $compiler->getTemplate()->getLeftDelimiter() . "{$_openTag}" .
|
||||
$compiler->getTemplate()->getRightDelimiter() . "' tag");
|
||||
return;
|
||||
}
|
||||
// wrong nesting of tags
|
||||
$compiler->trigger_template_error('unexpected closing tag', null, true);
|
||||
protected function closeTag(Template $compiler, $expectedTag) {
|
||||
return $compiler->closeTag($expectedTag);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -259,11 +224,11 @@ abstract class Base implements CompilerInterface {
|
||||
* Compiles code for the tag
|
||||
*
|
||||
* @param array $args array with attributes from parser
|
||||
* @param \Smarty\Compiler\Template $compiler compiler object
|
||||
* @param Template $compiler compiler object
|
||||
* @param array $parameter array with compilation parameter
|
||||
*
|
||||
* @return bool|string compiled code or true if no code has been compiled
|
||||
* @throws \Smarty\CompilerException
|
||||
*/
|
||||
abstract public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = array(), $tag = null, $function = null);
|
||||
abstract public function compile($args, Template $compiler, $parameter = array(), $tag = null, $function = null);
|
||||
}
|
||||
|
@@ -18,8 +18,6 @@ use Smarty\Smarty;
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Block Plugin Class
|
||||
*
|
||||
|
||||
|
||||
*/
|
||||
class BlockCompiler extends Base {
|
||||
|
||||
@@ -62,6 +60,56 @@ class BlockCompiler extends Base {
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles code for the {$smarty.block.child} property
|
||||
*
|
||||
* @param Template $compiler compiler object
|
||||
*
|
||||
* @return string compiled code
|
||||
* @throws CompilerException
|
||||
*/
|
||||
public function compileChild(\Smarty\Compiler\Template $compiler) {
|
||||
|
||||
if (!isset($compiler->_cache['blockNesting'])) {
|
||||
$compiler->trigger_template_error(
|
||||
"{\$smarty.block.child} used outside {block} tags ",
|
||||
$compiler->getParser()->lex->taglineno
|
||||
);
|
||||
}
|
||||
$compiler->has_code = true;
|
||||
$compiler->suppressNocacheProcessing = true;
|
||||
|
||||
$output = "<?php \n";
|
||||
$output .= '$_smarty_tpl->getInheritance()->callChild($_smarty_tpl, $this' . ");\n";
|
||||
$output .= "?>\n";
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles code for the {$smarty.block.parent} property
|
||||
*
|
||||
* @param Template $compiler compiler object
|
||||
*
|
||||
* @return string compiled code
|
||||
* @throws CompilerException
|
||||
*/
|
||||
public function compileParent(\Smarty\Compiler\Template $compiler) {
|
||||
|
||||
if (!isset($compiler->_cache['blockNesting'])) {
|
||||
$compiler->trigger_template_error(
|
||||
"{\$smarty.block.parent} used outside {block} tags ",
|
||||
$compiler->getParser()->lex->taglineno
|
||||
);
|
||||
}
|
||||
$compiler->has_code = true;
|
||||
$compiler->suppressNocacheProcessing = true;
|
||||
|
||||
$output = "<?php \n";
|
||||
$output .= '$_smarty_tpl->getInheritance()->callParent($_smarty_tpl, $this' . ");\n";
|
||||
$output .= "?>\n";
|
||||
return $output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if this block is cacheable.
|
||||
*
|
||||
@@ -118,6 +166,13 @@ class BlockCompiler extends Base {
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
|
||||
if ($compiler->tag_nocache) {
|
||||
// push a {nocache} tag onto the stack to prevent caching of this block
|
||||
$this->openTag($compiler, 'nocache');
|
||||
}
|
||||
|
||||
$this->openTag($compiler, $tag, [$_params, $compiler->tag_nocache]);
|
||||
|
||||
// compile code
|
||||
$output = "<?php \$_block_repeat=true;
|
||||
if (!" . $this->getIsCallableCode($tag, $function) .") {\nthrow new \\Smarty\\Exception('block tag \'{$tag}\' not callable or registered');\n}\n
|
||||
@@ -125,9 +180,7 @@ echo " . $this->getFullCallbackCode($tag, $function) . "({$_params}, null, \$_sm
|
||||
while (\$_block_repeat) {
|
||||
ob_start();
|
||||
?>";
|
||||
$this->openTag($compiler, $tag, [$_params, $compiler->nocache]);
|
||||
// maybe nocache because of nocache variables or nocache plugin
|
||||
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
@@ -142,13 +195,11 @@ while (\$_block_repeat) {
|
||||
* @throws Exception
|
||||
*/
|
||||
private function compileClosingTag(Template $compiler, string $tag, array $parameter, ?string $function): string {
|
||||
// must endblock be nocache?
|
||||
if ($compiler->nocache) {
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
|
||||
// closing tag of block plugin, restore nocache
|
||||
$base_tag = substr($tag, 0, -5);
|
||||
[$_params, $compiler->nocache] = $this->closeTag($compiler, $base_tag);
|
||||
[$_params, $nocache_pushed] = $this->closeTag($compiler, $base_tag);
|
||||
|
||||
// compile code
|
||||
if (!isset($parameter['modifier_list'])) {
|
||||
$mod_pre = $mod_post = $mod_content = '';
|
||||
@@ -164,6 +215,13 @@ while (\$_block_repeat) {
|
||||
$callback = $this->getFullCallbackCode($base_tag, $function);
|
||||
$output .= "echo {$callback}({$_params}, {$mod_content2}, \$_smarty_tpl, \$_block_repeat);\n";
|
||||
$output .= "{$mod_post}}\n?>";
|
||||
|
||||
if ($nocache_pushed) {
|
||||
// pop the pushed virtual nocache tag
|
||||
$this->closeTag($compiler, 'nocache');
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
|
||||
|
@@ -19,6 +19,12 @@ namespace Smarty\Compile\Tag;
|
||||
*/
|
||||
class Append extends Assign
|
||||
{
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected $optional_attributes = ['scope', 'index'];
|
||||
|
||||
/**
|
||||
* Compiles code for the {append} tag
|
||||
*
|
||||
@@ -31,13 +37,10 @@ class Append extends Assign
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = array(), $tag = null, $function = null)
|
||||
{
|
||||
// the following must be assigned at runtime because it will be overwritten in parent class
|
||||
$this->required_attributes = array('var', 'value');
|
||||
$this->shorttag_order = array('var', 'value');
|
||||
$this->optional_attributes = array('scope', 'index');
|
||||
$this->mapCache = array();
|
||||
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
|
||||
// map to compile assign attributes
|
||||
if (isset($_attr[ 'index' ])) {
|
||||
$_params[ 'smarty_internal_index' ] = '[' . $_attr[ 'index' ] . ']';
|
||||
|
@@ -22,6 +22,21 @@ use Smarty\Smarty;
|
||||
*/
|
||||
class Assign extends Base
|
||||
{
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected $required_attributes = ['var', 'value'];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected $optional_attributes = ['scope'];
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
*/
|
||||
protected $shorttag_order = ['var', 'value'];
|
||||
|
||||
/**
|
||||
* Attribute definition: Overwrites base class.
|
||||
*
|
||||
@@ -42,21 +57,17 @@ class Assign extends Base
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = array(), $tag = null, $function = null)
|
||||
{
|
||||
// the following must be assigned at runtime because it will be overwritten in Append
|
||||
$this->required_attributes = array('var', 'value');
|
||||
$this->shorttag_order = array('var', 'value');
|
||||
$this->optional_attributes = array('scope');
|
||||
$this->mapCache = array();
|
||||
|
||||
$_nocache = false;
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
// nocache ?
|
||||
|
||||
if ($_var = $compiler->getId($_attr[ 'var' ])) {
|
||||
$_var = "'{$_var}'";
|
||||
} else {
|
||||
$_var = $_attr[ 'var' ];
|
||||
}
|
||||
if ($compiler->tag_nocache || $compiler->nocache) {
|
||||
if ($compiler->tag_nocache || $compiler->isNocacheActive()) {
|
||||
$_nocache = true;
|
||||
// create nocache var to make it know for further compiling
|
||||
$compiler->setNocacheInVariable($_attr[ 'var' ]);
|
||||
|
@@ -74,20 +74,17 @@ class Block extends Inheritance {
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
++$compiler->_cache['blockNesting'];
|
||||
$_className = 'Block_' . preg_replace('![^\w]+!', '_', uniqid(mt_rand(), true));
|
||||
$compiler->_cache['blockName'][$compiler->_cache['blockNesting']] = $_attr['name'];
|
||||
$compiler->_cache['blockClass'][$compiler->_cache['blockNesting']] = $_className;
|
||||
$compiler->_cache['blockParams'][$compiler->_cache['blockNesting']] = [];
|
||||
$compiler->_cache['blockParams'][1]['subBlocks'][trim($_attr['name'], '"\'')][] = $_className;
|
||||
|
||||
$this->openTag(
|
||||
$compiler,
|
||||
'block',
|
||||
[
|
||||
$_attr, $compiler->nocache, $compiler->getParser()->current_buffer,
|
||||
$compiler->getTemplate()->getCompiled()->getNocacheCode(),
|
||||
$compiler->getTemplate()->caching,
|
||||
$_attr, $compiler->tag_nocache, $compiler->getParser()->current_buffer,
|
||||
$compiler->getTemplate()->getCompiled()->getNocacheCode(), $_className
|
||||
]
|
||||
);
|
||||
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
||||
|
||||
// @TODO what is this for?
|
||||
$compiler->getParser()->current_buffer = new Template();
|
||||
$compiler->getTemplate()->getCompiled()->setNocacheCode(false);
|
||||
$compiler->suppressNocacheProcessing = true;
|
||||
|
@@ -1,26 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Smarty.
|
||||
*
|
||||
* (c) 2015 Uwe Tews
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Smarty\Compile\Tag;
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Block Child Class
|
||||
*
|
||||
* @author Uwe Tews <uwe.tews@googlemail.com>
|
||||
*/
|
||||
class BlockChild extends Child {
|
||||
|
||||
/**
|
||||
* Tag name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $tag = 'block_child';
|
||||
}
|
@@ -20,19 +20,11 @@ class BlockClose extends Inheritance {
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = array(), $tag = null, $function = null)
|
||||
{
|
||||
[$_attr, $_nocache, $_buffer, $_has_nocache_code, $_caching] = $this->closeTag($compiler, ['block']);
|
||||
// init block parameter
|
||||
$_block = $compiler->_cache['blockParams'][$compiler->_cache['blockNesting']];
|
||||
unset($compiler->_cache['blockParams'][$compiler->_cache['blockNesting']]);
|
||||
[$_attr, $_nocache, $_buffer, $_has_nocache_code, $_className] = $this->closeTag($compiler, ['block']);
|
||||
|
||||
$_name = $_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] = 'true';
|
||||
}
|
||||
}
|
||||
$_className = $compiler->_cache['blockClass'][$compiler->_cache['blockNesting']];
|
||||
$_assign = $_attr['assign'] ?? null;
|
||||
|
||||
// get compiled block code
|
||||
$_functionCode = $compiler->getParser()->current_buffer;
|
||||
// setup buffer for template function code
|
||||
@@ -41,9 +33,6 @@ class BlockClose extends Inheritance {
|
||||
$output .= $compiler->cStyleComment(" {block {$_name}} ") . "\n";
|
||||
$output .= "class {$_className} extends \\Smarty\\Runtime\\Block\n";
|
||||
$output .= "{\n";
|
||||
foreach ($_block as $property => $value) {
|
||||
$output .= "public \${$property} = " . var_export($value, true) . ";\n";
|
||||
}
|
||||
$output .= "public function callBlock(\\Smarty\\Template \$_smarty_tpl) {\n";
|
||||
if ($compiler->getTemplate()->getCompiled()->getNocacheCode()) {
|
||||
$output .= "\$_smarty_tpl->getCached()->hashes['{$compiler->getTemplate()->getCompiled()->nocache_hash}'] = true;\n";
|
||||
@@ -76,11 +65,13 @@ class BlockClose extends Inheritance {
|
||||
)
|
||||
);
|
||||
$compiler->blockOrFunctionCode .= $compiler->getParser()->current_buffer->to_smarty_php($compiler->getParser());
|
||||
|
||||
$compiler->getParser()->current_buffer = new Template();
|
||||
|
||||
// restore old status
|
||||
$compiler->getTemplate()->getCompiled()->setNocacheCode($_has_nocache_code);
|
||||
$compiler->tag_nocache = $compiler->nocache;
|
||||
$compiler->nocache = $_nocache;
|
||||
$compiler->tag_nocache = $_nocache;
|
||||
|
||||
$compiler->getParser()->current_buffer = $_buffer;
|
||||
$output = "<?php \n";
|
||||
if ($compiler->_cache['blockNesting'] === 1) {
|
||||
|
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Smarty.
|
||||
*
|
||||
* (c) 2015 Uwe Tews
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Smarty\Compile\Tag;
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Block Parent Class
|
||||
*
|
||||
* @author Uwe Tews <uwe.tews@googlemail.com>
|
||||
*/
|
||||
class BlockParent extends Child {
|
||||
|
||||
/**
|
||||
* Tag name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $tag = 'block_parent';
|
||||
|
||||
/**
|
||||
* Block type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $blockType = 'Parent';
|
||||
}
|
@@ -93,17 +93,20 @@ class BreakTag extends Base {
|
||||
$levels = 1;
|
||||
}
|
||||
$level_count = $levels;
|
||||
$stack_count = count($compiler->_tag_stack) - 1;
|
||||
|
||||
$tagStack = $compiler->getTagStack();
|
||||
$stack_count = count($tagStack) - 1;
|
||||
|
||||
$foreachLevels = 0;
|
||||
$lastTag = '';
|
||||
while ($level_count > 0 && $stack_count >= 0) {
|
||||
if (isset($_is_loopy[$compiler->_tag_stack[$stack_count][0]])) {
|
||||
$lastTag = $compiler->_tag_stack[$stack_count][0];
|
||||
if (isset($_is_loopy[$tagStack[$stack_count][0]])) {
|
||||
$lastTag = $tagStack[$stack_count][0];
|
||||
if ($level_count === 0) {
|
||||
break;
|
||||
}
|
||||
$level_count--;
|
||||
if ($compiler->_tag_stack[$stack_count][0] === 'foreach') {
|
||||
if ($tagStack[$stack_count][0] === 'foreach') {
|
||||
$foreachLevels++;
|
||||
}
|
||||
}
|
||||
|
@@ -59,7 +59,7 @@ class Call extends Base {
|
||||
$_name = $_attr['name'];
|
||||
unset($_attr['name'], $_attr['assign'], $_attr['nocache']);
|
||||
// set flag (compiled code of {function} must be included in cache file
|
||||
if (!$compiler->getTemplate()->caching || $compiler->nocache || $compiler->tag_nocache) {
|
||||
if (!$compiler->getTemplate()->caching || $compiler->isNocacheActive() || $compiler->tag_nocache) {
|
||||
$_nocache = 'true';
|
||||
} else {
|
||||
$_nocache = 'false';
|
||||
|
@@ -55,13 +55,17 @@ class Capture extends Base {
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args, $parameter, 'capture');
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
$buffer = $_attr['name'] ?? "'default'";
|
||||
$assign = $_attr['assign'] ?? 'null';
|
||||
$append = $_attr['append'] ?? 'null';
|
||||
$compiler->_cache['capture_stack'][] = [$compiler->nocache];
|
||||
// maybe nocache because of nocache variables
|
||||
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
||||
|
||||
$compiler->_cache['capture_stack'][] = $compiler->tag_nocache;
|
||||
if ($compiler->tag_nocache) {
|
||||
// push a virtual {nocache} tag onto the stack.
|
||||
$compiler->openTag('nocache');
|
||||
}
|
||||
|
||||
$_output = "<?php \$_smarty_tpl->getSmarty()->getRuntime('Capture')->open(\$_smarty_tpl, $buffer, $assign, $append);?>";
|
||||
return $_output;
|
||||
}
|
||||
|
@@ -30,13 +30,13 @@ class CaptureClose extends Base {
|
||||
* @return string compiled code
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args, $parameter, '/capture');
|
||||
// must endblock be nocache?
|
||||
if ($compiler->nocache) {
|
||||
|
||||
if (array_pop($compiler->_cache['capture_stack'])) {
|
||||
// pop the virtual {nocache} tag from the stack.
|
||||
$compiler->closeTag('nocache');
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
[$compiler->nocache] = array_pop($compiler->_cache['capture_stack']);
|
||||
|
||||
return "<?php \$_smarty_tpl->getSmarty()->getRuntime('Capture')->close(\$_smarty_tpl);?>";
|
||||
}
|
||||
}
|
||||
|
@@ -1,82 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Smarty.
|
||||
*
|
||||
* (c) 2015 Uwe Tews
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Smarty\Compile\Tag;
|
||||
|
||||
use Smarty\Compile\Base;
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Child Class
|
||||
*
|
||||
* @author Uwe Tews <uwe.tews@googlemail.com>
|
||||
*/
|
||||
class Child extends Base {
|
||||
|
||||
/**
|
||||
* Attribute definition: Overwrites base class.
|
||||
*
|
||||
* @var array
|
||||
* @see BasePlugin
|
||||
*/
|
||||
protected $optional_attributes = ['assign'];
|
||||
|
||||
/**
|
||||
* Tag name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $tag = 'child';
|
||||
|
||||
/**
|
||||
* Block type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $blockType = 'Child';
|
||||
|
||||
/**
|
||||
* Compiles code for the {child} tag
|
||||
*
|
||||
* @param array $args array with attributes from parser
|
||||
* @param \Smarty\Compiler\Template $compiler compiler object
|
||||
* @param array $parameter array with compilation parameter
|
||||
*
|
||||
* @return string compiled code
|
||||
* @throws \Smarty\CompilerException
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
$tag = isset($parameter[0]) ? "'{$parameter[0]}'" : "'{{$this->tag}}'";
|
||||
if (!isset($compiler->_cache['blockNesting'])) {
|
||||
$compiler->trigger_template_error(
|
||||
"{$tag} used outside {block} tags ",
|
||||
$compiler->getParser()->lex->taglineno
|
||||
);
|
||||
}
|
||||
$compiler->has_code = true;
|
||||
$compiler->suppressNocacheProcessing = true;
|
||||
if ($this->blockType === 'Child') {
|
||||
$compiler->_cache['blockParams'][$compiler->_cache['blockNesting']]['callsChild'] = 'true';
|
||||
}
|
||||
$_assign = $_attr['assign'] ?? null;
|
||||
$output = "<?php \n";
|
||||
if (isset($_assign)) {
|
||||
$output .= "ob_start();\n";
|
||||
}
|
||||
$output .= '$_smarty_tpl->getInheritance()->call' . $this->blockType . '($_smarty_tpl, $this' .
|
||||
($this->blockType === 'Child' ? '' : ", {$tag}") . ");\n";
|
||||
if (isset($_assign)) {
|
||||
$output .= "\$_smarty_tpl->assign({$_assign}, ob_get_clean());\n";
|
||||
}
|
||||
$output .= "?>\n";
|
||||
return $output;
|
||||
}
|
||||
}
|
@@ -23,9 +23,9 @@ class ElseIfTag extends Base {
|
||||
* @throws \Smarty\CompilerException
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
[$nesting, $compiler->tag_nocache] = $this->closeTag($compiler, ['if', 'elseif']);
|
||||
|
||||
[$nesting, $nocache_pushed] = $this->closeTag($compiler, ['if', 'elseif']);
|
||||
|
||||
if (!isset($parameter['if condition'])) {
|
||||
$compiler->trigger_template_error('missing elseif condition', null, true);
|
||||
}
|
||||
@@ -38,7 +38,7 @@ class ElseIfTag extends Base {
|
||||
} else {
|
||||
$var = $parameter['if condition']['var'];
|
||||
}
|
||||
if ($compiler->nocache) {
|
||||
if ($compiler->isNocacheActive()) {
|
||||
// create nocache var to make it know for further compiling
|
||||
$compiler->setNocacheInVariable($var);
|
||||
}
|
||||
@@ -68,12 +68,12 @@ class ElseIfTag extends Base {
|
||||
$_output = $compiler->appendCode("<?php } else {\n?>", $assignCode);
|
||||
return $compiler->appendCode($_output, "<?php if ({$prefixVar}) {?>");
|
||||
} else {
|
||||
$this->openTag($compiler, 'elseif', [$nesting, $compiler->tag_nocache]);
|
||||
$this->openTag($compiler, 'elseif', [$nesting, $nocache_pushed]);
|
||||
return "<?php } elseif ({$parameter['if condition']}) {?>";
|
||||
}
|
||||
} else {
|
||||
$_output = $compiler->appendCode("<?php } else {\n?>", $prefixCode);
|
||||
$this->openTag($compiler, 'elseif', [$nesting + 1, $compiler->tag_nocache]);
|
||||
$this->openTag($compiler, 'elseif', [$nesting + 1, $nocache_pushed]);
|
||||
if ($condition_by_assign) {
|
||||
$_output = $compiler->appendCode($_output, $assignCode);
|
||||
return $compiler->appendCode($_output, "<?php if ({$prefixVar}) {?>");
|
||||
|
@@ -31,18 +31,20 @@ class ForClose extends Base {
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
$compiler->loopNesting--;
|
||||
// check and get attributes
|
||||
$this->getAttributes($compiler, $args);
|
||||
// must endblock be nocache?
|
||||
if ($compiler->nocache) {
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
[$openTag, $compiler->nocache] = $this->closeTag($compiler, ['for', 'forelse']);
|
||||
|
||||
[$openTag, $nocache_pushed] = $this->closeTag($compiler, ['for', 'forelse']);
|
||||
$output = "<?php }\n";
|
||||
if ($openTag !== 'forelse') {
|
||||
$output .= "}\n";
|
||||
}
|
||||
$output .= "?>";
|
||||
|
||||
if ($nocache_pushed) {
|
||||
// pop the pushed virtual nocache tag
|
||||
$this->closeTag('nocache');
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
||||
|
@@ -22,10 +22,8 @@ class ForElse extends Base {
|
||||
* @return string compiled code
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
// check and get attributes
|
||||
$this->getAttributes($compiler, $args);
|
||||
[$openTag, $nocache] = $this->closeTag($compiler, ['for']);
|
||||
$this->openTag($compiler, 'forelse', ['forelse', $nocache]);
|
||||
[$tagName, $nocache_pushed] = $this->closeTag($compiler, ['for']);
|
||||
$this->openTag($compiler, 'forelse', ['forelse', $nocache_pushed]);
|
||||
return "<?php }} else { ?>";
|
||||
}
|
||||
}
|
@@ -37,7 +37,7 @@ class ForTag extends Base {
|
||||
$this->required_attributes = ['start', 'ifexp', 'var', 'step'];
|
||||
$this->optional_attributes = [];
|
||||
}
|
||||
$this->mapCache = [];
|
||||
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
$output = "<?php\n";
|
||||
@@ -87,10 +87,14 @@ class ForTag extends Base {
|
||||
$output .= "\$_smarty_tpl->tpl_vars[$var]->last = \$_smarty_tpl->tpl_vars[$var]->iteration === \$_smarty_tpl->tpl_vars[$var]->total;";
|
||||
}
|
||||
$output .= '?>';
|
||||
$this->openTag($compiler, 'for', ['for', $compiler->nocache]);
|
||||
// maybe nocache because of nocache variables
|
||||
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
||||
// return compiled code
|
||||
|
||||
if ($compiler->tag_nocache) {
|
||||
// push a {nocache} tag onto the stack to prevent caching of this for loop
|
||||
$this->openTag('nocache');
|
||||
}
|
||||
|
||||
$this->openTag($compiler, 'for', ['for', $compiler->tag_nocache]);
|
||||
|
||||
return $output;
|
||||
}
|
||||
}
|
@@ -31,13 +31,15 @@ class ForeachClose extends Base {
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
$compiler->loopNesting--;
|
||||
// must endblock be nocache?
|
||||
if ($compiler->nocache) {
|
||||
|
||||
[$openTag, $nocache_pushed, $local, $itemVar, $restore] = $this->closeTag($compiler, ['foreach', 'foreachelse']);
|
||||
|
||||
if ($nocache_pushed) {
|
||||
// pop the pushed virtual nocache tag
|
||||
$this->closeTag('nocache');
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
[
|
||||
$openTag, $compiler->nocache, $local, $itemVar, $restore,
|
||||
] = $this->closeTag($compiler, ['foreach', 'foreachelse']);
|
||||
|
||||
$output = "<?php\n";
|
||||
if ($restore === 2) {
|
||||
$output .= "{$itemVar} = {$local}saved;\n";
|
||||
|
@@ -21,10 +21,9 @@ class ForeachElse extends Base {
|
||||
* @return string compiled code
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
// check and get attributes
|
||||
$this->getAttributes($compiler, $args);
|
||||
[$openTag, $nocache, $local, $itemVar, $restore] = $this->closeTag($compiler, ['foreach']);
|
||||
$this->openTag($compiler, 'foreachelse', ['foreachelse', $nocache, $local, $itemVar, 0]);
|
||||
|
||||
[$openTag, $nocache_pushed, $local, $itemVar, $restore] = $this->closeTag($compiler, ['foreach']);
|
||||
$this->openTag($compiler, 'foreachelse', ['foreachelse', $nocache_pushed, $local, $itemVar, 0]);
|
||||
$output = "<?php\n";
|
||||
if ($restore === 2) {
|
||||
$output .= "{$itemVar} = {$local}saved;\n";
|
||||
|
@@ -181,14 +181,19 @@ class ForeachTag extends ForeachSection {
|
||||
$foreachVar = "\$_smarty_tpl->tpl_vars['__smarty_foreach_{$attributes['name']}']";
|
||||
}
|
||||
$needTotal = isset($itemAttr['total']);
|
||||
|
||||
if ($compiler->tag_nocache) {
|
||||
// push a {nocache} tag onto the stack to prevent caching of this block
|
||||
$this->openTag('nocache');
|
||||
}
|
||||
|
||||
// Register tag
|
||||
$this->openTag(
|
||||
$compiler,
|
||||
'foreach',
|
||||
['foreach', $compiler->nocache, $local, $itemVar, empty($itemAttr) ? 1 : 2]
|
||||
['foreach', $compiler->tag_nocache, $local, $itemVar, empty($itemAttr) ? 1 : 2]
|
||||
);
|
||||
// maybe nocache because of nocache variables
|
||||
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
||||
|
||||
// generate output code
|
||||
$output = "<?php\n";
|
||||
$output .= "\$_from = \$_smarty_tpl->getSmarty()->getRuntime('Foreach')->init(\$_smarty_tpl, $from, " .
|
||||
|
@@ -29,11 +29,15 @@ class IfClose extends Base {
|
||||
* @return string compiled code
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
// must endblock be nocache?
|
||||
if ($compiler->nocache) {
|
||||
|
||||
[$nesting, $nocache_pushed] = $this->closeTag($compiler, ['if', 'else', 'elseif']);
|
||||
|
||||
if ($nocache_pushed) {
|
||||
// pop the pushed virtual nocache tag
|
||||
$this->closeTag('nocache');
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
[$nesting, $compiler->nocache] = $this->closeTag($compiler, ['if', 'else', 'elseif']);
|
||||
|
||||
$tmp = '';
|
||||
for ($i = 0; $i < $nesting; $i++) {
|
||||
$tmp .= '}';
|
||||
|
@@ -23,11 +23,14 @@ class IfTag extends Base {
|
||||
* @throws \Smarty\CompilerException
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
$this->openTag($compiler, 'if', [1, $compiler->nocache]);
|
||||
// must whole block be nocache ?
|
||||
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
||||
|
||||
if ($compiler->tag_nocache) {
|
||||
// push a {nocache} tag onto the stack to prevent caching of this block
|
||||
$this->openTag('nocache');
|
||||
}
|
||||
|
||||
$this->openTag($compiler, 'if', [1, $compiler->tag_nocache]);
|
||||
|
||||
if (!isset($parameter['if condition'])) {
|
||||
$compiler->trigger_template_error('missing if condition', null, true);
|
||||
}
|
||||
@@ -37,7 +40,7 @@ class IfTag extends Base {
|
||||
} else {
|
||||
$var = $parameter['if condition']['var'];
|
||||
}
|
||||
if ($compiler->nocache) {
|
||||
if ($compiler->isNocacheActive()) {
|
||||
// create nocache var to make it know for further compiling
|
||||
$compiler->setNocacheInVariable($var);
|
||||
}
|
||||
|
@@ -111,11 +111,13 @@ class IncludeTag extends Base {
|
||||
|
||||
// assume caching is off
|
||||
$_caching = Smarty::CACHING_OFF;
|
||||
$call_nocache = $compiler->tag_nocache || $compiler->nocache;
|
||||
|
||||
// caching was on and {include} is not in nocache mode
|
||||
if ($compiler->getTemplate()->caching && !$compiler->nocache && !$compiler->tag_nocache) {
|
||||
// @TODO see if we can do without this
|
||||
if ($compiler->getTemplate()->caching && !$compiler->isNocacheActive()) {
|
||||
$_caching = \Smarty\Template::CACHING_NOCACHE_CODE;
|
||||
}
|
||||
|
||||
// flag if included template code should be merged into caller
|
||||
$merge_compiled_includes = ($compiler->getSmarty()->merge_compiled_includes || $_attr['inline'] === true) &&
|
||||
!$compiler->getTemplate()->getSource()->handler->recompiled;
|
||||
@@ -125,12 +127,15 @@ class IncludeTag extends Base {
|
||||
$merge_compiled_includes = false;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* if the {include} tag provides individual parameter for caching or compile_id
|
||||
* the subtemplate must not be included into the common cache file and is treated like
|
||||
* a call in nocache mode.
|
||||
*
|
||||
*/
|
||||
|
||||
$call_nocache = $compiler->isNocacheActive();
|
||||
if ($_attr['nocache'] !== true && $_attr['caching']) {
|
||||
$_caching = $_new_caching = (int)$_attr['caching'];
|
||||
$call_nocache = true;
|
||||
@@ -161,7 +166,7 @@ class IncludeTag extends Base {
|
||||
// output will be stored in a smarty variable instead of being displayed
|
||||
if ($_assign = $compiler->getId($_attr['assign'])) {
|
||||
$_assign = "'{$_assign}'";
|
||||
if ($compiler->tag_nocache || $compiler->nocache || $call_nocache) {
|
||||
if ($call_nocache) {
|
||||
// create nocache var to make it know for further compiling
|
||||
$compiler->setNocacheInVariable($_attr['assign']);
|
||||
}
|
||||
@@ -281,7 +286,7 @@ class IncludeTag extends Base {
|
||||
$compiled_code = "<?php\n\n";
|
||||
$compiled_code .= $compiler->cStyleComment(" Start inline template \"{$sourceInfo}\" =============================") . "\n";
|
||||
$compiled_code .= "function {$tpl->getCompiled()->unifunc} (\\Smarty\\Template \$_smarty_tpl) {\n";
|
||||
$compiled_code .= "?>\n" . $tpl->getCompiler()->compileTemplateSource($tpl, null, $compiler->getParentCompiler());
|
||||
$compiled_code .= "?>\n" . $tpl->getCompiler()->compileTemplateSource($tpl, $compiler->getParentCompiler());
|
||||
$compiled_code .= "<?php\n";
|
||||
$compiled_code .= "}\n?>\n";
|
||||
$compiled_code .= $tpl->getSmarty()->runPostFilters($tpl->getCompiler()->blockOrFunctionCode, $tpl);
|
||||
|
@@ -29,10 +29,7 @@ class Nocache extends Base {
|
||||
* @return bool
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
$this->getAttributes($compiler, $args);
|
||||
$this->openTag($compiler, 'nocache', [$compiler->nocache]);
|
||||
// enter nocache mode
|
||||
$compiler->nocache = true;
|
||||
$this->openTag($compiler, 'nocache');
|
||||
// this tag does not return compiled code
|
||||
$compiler->has_code = false;
|
||||
return true;
|
||||
|
@@ -30,9 +30,7 @@ class NocacheClose extends Base {
|
||||
* @return bool
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
// leave nocache mode
|
||||
[$compiler->nocache] = $this->closeTag($compiler, ['nocache']);
|
||||
$this->closeTag($compiler, ['nocache']);
|
||||
// this tag does not return compiled code
|
||||
$compiler->has_code = false;
|
||||
return true;
|
||||
|
@@ -1,33 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* This file is part of Smarty.
|
||||
*
|
||||
* (c) 2015 Uwe Tews
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Smarty\Compile\Tag;
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Parent Class
|
||||
*
|
||||
* @author Uwe Tews <uwe.tews@googlemail.com>
|
||||
*/
|
||||
class ParentTag extends Child {
|
||||
|
||||
/**
|
||||
* Tag name
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $tag = 'parent';
|
||||
|
||||
/**
|
||||
* Block type
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $blockType = 'Parent';
|
||||
}
|
@@ -95,9 +95,14 @@ class Section extends ForeachSection {
|
||||
}
|
||||
$local = "\$__section_{$attributes['name']}_" . $this->counter++ . '_';
|
||||
$sectionVar = "\$_smarty_tpl->tpl_vars['__smarty_section_{$attributes['name']}']";
|
||||
$this->openTag($compiler, 'section', ['section', $compiler->nocache, $local, $sectionVar]);
|
||||
// maybe nocache because of nocache variables
|
||||
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
||||
|
||||
if ($compiler->tag_nocache) {
|
||||
// push a {nocache} tag onto the stack to prevent caching of this block
|
||||
$this->openTag('nocache');
|
||||
}
|
||||
|
||||
$this->openTag($compiler, 'section', ['section', $compiler->tag_nocache]);
|
||||
|
||||
$initLocal = [];
|
||||
$initNamedProperty = [];
|
||||
$initFor = [];
|
||||
|
@@ -14,9 +14,6 @@ use Smarty\Compile\Base;
|
||||
|
||||
/**
|
||||
* Smarty Internal Plugin Compile Sectionclose Class
|
||||
*
|
||||
|
||||
|
||||
*/
|
||||
class SectionClose extends Base {
|
||||
|
||||
@@ -30,12 +27,14 @@ class SectionClose extends Base {
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
$compiler->loopNesting--;
|
||||
// must endblock be nocache?
|
||||
if ($compiler->nocache) {
|
||||
$compiler->tag_nocache = true;
|
||||
|
||||
[$openTag, $nocache_pushed] = $this->closeTag($compiler, ['section', 'sectionelse']);
|
||||
|
||||
if ($nocache_pushed) {
|
||||
// pop the pushed virtual nocache tag
|
||||
$this->closeTag('nocache');
|
||||
}
|
||||
[$openTag, $compiler->nocache, $local, $sectionVar] =
|
||||
$this->closeTag($compiler, ['section', 'sectionelse']);
|
||||
|
||||
$output = "<?php\n";
|
||||
if ($openTag === 'sectionelse') {
|
||||
$output .= "}\n";
|
||||
|
@@ -21,10 +21,8 @@ class SectionElse extends Base {
|
||||
* @return string compiled code
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
// check and get attributes
|
||||
$this->getAttributes($compiler, $args);
|
||||
[$openTag, $nocache, $local, $sectionVar] = $this->closeTag($compiler, ['section']);
|
||||
$this->openTag($compiler, 'sectionelse', ['sectionelse', $nocache, $local, $sectionVar]);
|
||||
[$openTag, $nocache_pushed] = $this->closeTag($compiler, ['section']);
|
||||
$this->openTag($compiler, 'sectionelse', ['sectionelse', $nocache_pushed]);
|
||||
return "<?php }} else {\n ?>";
|
||||
}
|
||||
}
|
@@ -30,11 +30,15 @@ class WhileClose extends Base {
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
$compiler->loopNesting--;
|
||||
// must endblock be nocache?
|
||||
if ($compiler->nocache) {
|
||||
|
||||
$nocache_pushed = $this->closeTag($compiler, ['while']);
|
||||
|
||||
if ($nocache_pushed) {
|
||||
// pop the pushed virtual nocache tag
|
||||
$this->closeTag('nocache');
|
||||
$compiler->tag_nocache = true;
|
||||
}
|
||||
$compiler->nocache = $this->closeTag($compiler, ['while']);
|
||||
|
||||
return "<?php }?>\n";
|
||||
}
|
||||
}
|
||||
|
@@ -24,16 +24,20 @@ class WhileTag extends Base {
|
||||
*/
|
||||
public function compile($args, \Smarty\Compiler\Template $compiler, $parameter = [], $tag = null, $function = null) {
|
||||
$compiler->loopNesting++;
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
$this->openTag($compiler, 'while', $compiler->nocache);
|
||||
|
||||
if ($compiler->tag_nocache) {
|
||||
// push a {nocache} tag onto the stack to prevent caching of this block
|
||||
$this->openTag('nocache');
|
||||
}
|
||||
|
||||
$this->openTag($compiler, 'while', $compiler->tag_nocache);
|
||||
|
||||
if (!array_key_exists('if condition', $parameter)) {
|
||||
$compiler->trigger_template_error('missing while condition', null, true);
|
||||
}
|
||||
// maybe nocache because of nocache variables
|
||||
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
||||
|
||||
if (is_array($parameter['if condition'])) {
|
||||
if ($compiler->nocache) {
|
||||
if ($compiler->isNocacheActive()) {
|
||||
// create nocache var to make it know for further compiling
|
||||
if (is_array($parameter['if condition']['var'])) {
|
||||
$var = $parameter['if condition']['var']['var'];
|
||||
|
@@ -17,6 +17,7 @@ use Smarty\Compile\ModifierCompiler;
|
||||
use Smarty\Compile\ObjectMethodBlockCompiler;
|
||||
use Smarty\Compile\ObjectMethodCallCompiler;
|
||||
use Smarty\Compile\FunctionCallCompiler;
|
||||
use Smarty\Compile\PrintExpressionCompiler;
|
||||
use Smarty\Lexer\TemplateLexer;
|
||||
use Smarty\Parser\TemplateParser;
|
||||
use Smarty\Smarty;
|
||||
@@ -76,14 +77,14 @@ class Template extends BaseCompiler {
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $_tag_stack = [];
|
||||
private $_tag_stack = [];
|
||||
|
||||
/**
|
||||
* tag stack count
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
public $_tag_stack_count = [];
|
||||
private $_tag_stack_count = [];
|
||||
|
||||
/**
|
||||
* current template
|
||||
@@ -308,6 +309,17 @@ class Template extends BaseCompiler {
|
||||
* @var ModifierCompiler
|
||||
*/
|
||||
private $modifierCompiler;
|
||||
/**
|
||||
* @var PrintExpressionCompiler
|
||||
*/
|
||||
private $printExpressionCompiler;
|
||||
|
||||
/**
|
||||
* Depth of nested {nocache}{/nocache} blocks. If outside, this is 0. If inside, this is 1 or higher (if nested).
|
||||
* @var int
|
||||
*/
|
||||
private $noCacheStackDepth = 0;
|
||||
|
||||
|
||||
/**
|
||||
* Initialize compiler
|
||||
@@ -332,53 +344,38 @@ class Template extends BaseCompiler {
|
||||
$this->defaultHandlerBlockCompiler = new DefaultHandlerBlockCompiler();
|
||||
$this->objectMethodBlockCompiler = new ObjectMethodBlockCompiler();
|
||||
$this->objectMethodCallCompiler = new ObjectMethodCallCompiler();
|
||||
$this->printExpressionCompiler = new PrintExpressionCompiler();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to compile a Smarty template
|
||||
*
|
||||
* @param Smarty\Template $template template object to compile
|
||||
* @param null $nocache true is shall be compiled in nocache mode
|
||||
* @param null|Template $parent_compiler
|
||||
* @param \Smarty\Template $template template object to compile
|
||||
*
|
||||
* @return bool true if compiling succeeded, false if it failed
|
||||
* @throws Exception
|
||||
*/
|
||||
public function compileTemplate(
|
||||
\Smarty\Template $template,
|
||||
$nocache = null,
|
||||
\Smarty\Compiler\Template $parent_compiler = null
|
||||
) {
|
||||
// get code frame of compiled template
|
||||
$_compiled_code = $template->createCodeFrame(
|
||||
$this->compileTemplateSource(
|
||||
$template,
|
||||
$nocache,
|
||||
$parent_compiler
|
||||
),
|
||||
public function compileTemplate(\Smarty\Template $template) {
|
||||
return $template->createCodeFrame(
|
||||
$this->compileTemplateSource($template),
|
||||
$this->smarty->runPostFilters($this->blockOrFunctionCode, $this->template) .
|
||||
join('', $this->mergedSubTemplatesCode),
|
||||
false,
|
||||
$this
|
||||
);
|
||||
return $_compiled_code;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compile template source and run optional post filter
|
||||
*
|
||||
* @param \Smarty\Template $template
|
||||
* @param null|bool $nocache flag if template must be compiled in nocache mode
|
||||
* @param \Smarty\Compiler\Template $parent_compiler
|
||||
* @param Template|null $parent_compiler
|
||||
*
|
||||
* @return string
|
||||
* @throws \Exception
|
||||
* @throws CompilerException
|
||||
* @throws Exception
|
||||
*/
|
||||
public function compileTemplateSource(
|
||||
\Smarty\Template $template,
|
||||
$nocache = null,
|
||||
\Smarty\Compiler\Template $parent_compiler = null
|
||||
) {
|
||||
public function compileTemplateSource(\Smarty\Template $template, \Smarty\Compiler\Template $parent_compiler = null) {
|
||||
try {
|
||||
// save template object in compiler class
|
||||
$this->template = $template;
|
||||
@@ -386,18 +383,20 @@ class Template extends BaseCompiler {
|
||||
$this->smarty->getDebug()->start_compile($this->template);
|
||||
}
|
||||
$this->parent_compiler = $parent_compiler ? $parent_compiler : $this;
|
||||
$nocache = isset($nocache) ? $nocache : false;
|
||||
|
||||
if (empty($template->getCompiled()->nocache_hash)) {
|
||||
$template->getCompiled()->nocache_hash = $this->nocache_hash;
|
||||
} else {
|
||||
$this->nocache_hash = $template->getCompiled()->nocache_hash;
|
||||
}
|
||||
$this->caching = $template->caching;
|
||||
|
||||
// flag for nocache sections
|
||||
$this->nocache = $nocache;
|
||||
$this->nocache = false;
|
||||
$this->tag_nocache = false;
|
||||
// reset has nocache code flag
|
||||
$this->template->getCompiled()->setNocacheCode(false);
|
||||
|
||||
$this->has_variable_string = false;
|
||||
$this->prefix_code = [];
|
||||
// add file dependency
|
||||
@@ -715,8 +714,7 @@ class Template extends BaseCompiler {
|
||||
if (!empty($content)
|
||||
&& !($this->template->getSource()->handler->recompiled)
|
||||
&& $this->caching
|
||||
&& !$this->suppressNocacheProcessing
|
||||
&& ($this->nocache || $this->tag_nocache)
|
||||
&& $this->isNocacheActive()
|
||||
) {
|
||||
$this->template->getCompiled()->setNocacheCode(true);
|
||||
$_output = addcslashes($content, '\'\\');
|
||||
@@ -1075,21 +1073,14 @@ class Template extends BaseCompiler {
|
||||
return '/*' . str_replace('*/', '* /', $string) . '*/';
|
||||
}
|
||||
|
||||
private function argsContainNocache(array $args): bool {
|
||||
foreach ($args as $arg) {
|
||||
if (!is_array($arg)) {
|
||||
if ($arg === "'nocache'" || $arg === 'nocache') {
|
||||
return true;
|
||||
}
|
||||
} else {
|
||||
foreach ($arg as $k => $v) {
|
||||
if (($k === "'nocache'" || $k === 'nocache') && (trim($v, "'\" ") === 'true')) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return false;
|
||||
public function compileChildBlock() {
|
||||
$this->has_code = true;
|
||||
return $this->blockCompiler->compileChild($this);
|
||||
}
|
||||
|
||||
public function compileParentBlock() {
|
||||
$this->has_code = true;
|
||||
return $this->blockCompiler->compileParent($this);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1108,17 +1099,16 @@ class Template extends BaseCompiler {
|
||||
// assume that tag does compile into code, but creates no HTML output
|
||||
$this->has_code = true;
|
||||
|
||||
// check nocache option flag
|
||||
if ($this->argsContainNocache($args)) {
|
||||
$this->tag_nocache = true;
|
||||
}
|
||||
$this->handleNocacheFlag($args);
|
||||
|
||||
// compile built-in tags
|
||||
if ($tagCompiler = $this->getTagCompiler($tag)) {
|
||||
if (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this)) {
|
||||
$this->tag_nocache = !$tagCompiler->isCacheable();
|
||||
$_output = $tagCompiler->compile($args, $this, $parameter);
|
||||
return $this->has_code ? $_output : null;
|
||||
if ($_output !== false) {
|
||||
return $this->has_code && $_output !== true ? $_output : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1190,6 +1180,21 @@ class Template extends BaseCompiler {
|
||||
$this->trigger_template_error("unknown tag '{$tag}'", null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets $this->tag_nocache if attributes contain the 'nocache' flag.
|
||||
*
|
||||
* @param array $attributes
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
private function handleNocacheFlag(array $attributes) {
|
||||
foreach ($attributes as $value) {
|
||||
if (is_string($value) && trim($value, '\'" ') == 'nocache') {
|
||||
$this->tag_nocache = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private function getBaseTag($tag) {
|
||||
if (strlen($tag) < 6 || substr($tag, -5) !== 'close') {
|
||||
return $tag;
|
||||
@@ -1198,6 +1203,24 @@ class Template extends BaseCompiler {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Compiles the output of a variable or expression.
|
||||
*
|
||||
* @param $value
|
||||
* @param $attributes
|
||||
* @param $modifiers
|
||||
*
|
||||
* @return string
|
||||
* @throws Exception
|
||||
*/
|
||||
public function compilePrintExpression($value, $attributes = [], $modifiers = null) {
|
||||
$this->handleNocacheFlag($attributes);
|
||||
return $this->printExpressionCompiler->compile($attributes, $this, [
|
||||
'value'=> $value,
|
||||
'modifierlist' => $modifiers,
|
||||
]);
|
||||
}
|
||||
|
||||
/**
|
||||
* method to compile a Smarty template
|
||||
*
|
||||
@@ -1256,7 +1279,7 @@ class Template extends BaseCompiler {
|
||||
mb_internal_encoding($mbEncoding);
|
||||
}
|
||||
// check for unclosed tags
|
||||
if (count($this->_tag_stack) > 0) {
|
||||
if ($this->getTagStackCount() > 0) {
|
||||
// get stacked info
|
||||
[$openTag, $_data] = array_pop($this->_tag_stack);
|
||||
$this->trigger_template_error(
|
||||
@@ -1405,4 +1428,72 @@ class Template extends BaseCompiler {
|
||||
$this->parent_compiler = $parent_compiler;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Push opening tag name on stack
|
||||
* Optionally additional data can be saved on stack
|
||||
*
|
||||
* @param string $openTag the opening tag's name
|
||||
* @param mixed $data optional data saved
|
||||
*/
|
||||
public function openTag($openTag, $data = null) {
|
||||
$this->_tag_stack[] = [$openTag, $data];
|
||||
if ($openTag == 'nocache') {
|
||||
$this->noCacheStackDepth++;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Pop closing tag
|
||||
* Raise an error if this stack-top doesn't match with expected opening tags
|
||||
*
|
||||
* @param array|string $expectedTag the expected opening tag names
|
||||
*
|
||||
* @return mixed any type the opening tag's name or saved data
|
||||
* @throws CompilerException
|
||||
*/
|
||||
public function closeTag($expectedTag) {
|
||||
if ($this->getTagStackCount() > 0) {
|
||||
// get stacked info
|
||||
[$_openTag, $_data] = array_pop($this->_tag_stack);
|
||||
// open tag must match with the expected ones
|
||||
if (in_array($_openTag, (array)$expectedTag)) {
|
||||
|
||||
if ($_openTag == 'nocache') {
|
||||
$this->noCacheStackDepth--;
|
||||
}
|
||||
|
||||
if (is_null($_data)) {
|
||||
// return opening tag
|
||||
return $_openTag;
|
||||
} else {
|
||||
// return restored data
|
||||
return $_data;
|
||||
}
|
||||
}
|
||||
// wrong nesting of tags
|
||||
$this->trigger_template_error("unclosed '" . $this->getTemplate()->getLeftDelimiter() . "{$_openTag}" .
|
||||
$this->getTemplate()->getRightDelimiter() . "' tag");
|
||||
return;
|
||||
}
|
||||
// wrong nesting of tags
|
||||
$this->trigger_template_error('unexpected closing tag', null, true);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if we are in a {nocache}...{/nocache} block, but false if inside {block} tag inside a {nocache} block...
|
||||
* @return bool
|
||||
*/
|
||||
public function isNocacheActive(): bool {
|
||||
return !$this->suppressNocacheProcessing && ($this->noCacheStackDepth > 0 || $this->tag_nocache);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the full tag stack, used in the compiler for {break}
|
||||
* @return array
|
||||
*/
|
||||
public function getTagStack(): array {
|
||||
return $this->_tag_stack;
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -13,9 +13,6 @@ class CoreExtension extends Base {
|
||||
case 'call': return new \Smarty\Compile\Tag\Call();
|
||||
case 'capture': return new \Smarty\Compile\Tag\Capture();
|
||||
case 'captureclose': return new \Smarty\Compile\Tag\CaptureClose();
|
||||
case 'child': return new \Smarty\Compile\Tag\Child();
|
||||
case 'block_child': return new \Smarty\Compile\Tag\BlockChild();
|
||||
case 'block_parent': return new \Smarty\Compile\Tag\BlockParent();
|
||||
case 'config_load': return new \Smarty\Compile\Tag\ConfigLoad();
|
||||
case 'continue': return new \Smarty\Compile\Tag\ContinueTag();
|
||||
case 'debug': return new \Smarty\Compile\Tag\Debug();
|
||||
@@ -38,7 +35,6 @@ class CoreExtension extends Base {
|
||||
case 'rdelim': return new \Smarty\Compile\Tag\Rdelim();
|
||||
case 'nocache': return new \Smarty\Compile\Tag\Nocache();
|
||||
case 'nocacheclose': return new \Smarty\Compile\Tag\NocacheClose();
|
||||
case 'parent': return new \Smarty\Compile\Tag\ParentTag();
|
||||
case 'section': return new \Smarty\Compile\Tag\Section();
|
||||
case 'sectionelse': return new \Smarty\Compile\Tag\SectionElse();
|
||||
case 'sectionclose': return new \Smarty\Compile\Tag\SectionClose();
|
||||
|
@@ -28,7 +28,7 @@ class Dq extends Base
|
||||
{
|
||||
$this->subtrees[] = $subtree;
|
||||
if ($subtree instanceof Tag) {
|
||||
$parser->block_nesting_level = count($parser->compiler->_tag_stack);
|
||||
$parser->block_nesting_level = $parser->compiler->getTagStackCount();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -64,7 +64,7 @@ class Dq extends Base
|
||||
$this->subtrees[] = $subtree;
|
||||
}
|
||||
if ($subtree instanceof Tag) {
|
||||
$parser->block_nesting_level = count($parser->compiler->_tag_stack);
|
||||
$parser->block_nesting_level = $parser->compiler->getTagStackCount();
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -64,7 +64,7 @@ class Tag extends Base
|
||||
$var = $parser->compiler->getNewPrefixVariable();
|
||||
$tmp = $parser->compiler->appendCode('<?php ob_start();?>', $this->data);
|
||||
$tmp = $parser->compiler->appendCode($tmp, "<?php {$var}=ob_get_clean();?>");
|
||||
$parser->compiler->prefix_code[] = sprintf('%s', $tmp);
|
||||
$parser->compiler->appendPrefixCode((string) $tmp);
|
||||
return $var;
|
||||
}
|
||||
}
|
||||
|
@@ -162,8 +162,8 @@ class TemplateParser
|
||||
{
|
||||
$this->lex = $lex;
|
||||
$this->compiler = $compiler;
|
||||
$this->template = $this->compiler->template;
|
||||
$this->smarty = $this->template->smarty;
|
||||
$this->template = $this->compiler->getTemplate();
|
||||
$this->smarty = $this->template->getSmarty();
|
||||
$this->security = $this->smarty->security_policy ?? false;
|
||||
$this->current_buffer = $this->root_buffer = new TemplateParseTree();
|
||||
}
|
||||
@@ -207,7 +207,7 @@ class TemplateParser
|
||||
}
|
||||
$this->compiler->prefix_code = array();
|
||||
$tmp .= $code;
|
||||
return new Tag($this, $this->compiler->processNocacheCode($tmp, true));
|
||||
return new Tag($this, $this->compiler->processNocacheCode($tmp));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -294,7 +294,7 @@ template ::= template smartytag(B). {
|
||||
$this->current_buffer->append_subtree($this, $this->mergePrefixCode(B));
|
||||
}
|
||||
$this->compiler->has_variable_string = false;
|
||||
$this->block_nesting_level = count($this->compiler->_tag_stack);
|
||||
$this->block_nesting_level = $this->compiler->getTagStackCount();
|
||||
}
|
||||
|
||||
|
||||
@@ -303,11 +303,12 @@ template ::= .
|
||||
|
||||
smartytag(A) ::= SIMPELOUTPUT(B). {
|
||||
$var = trim(substr(B, $this->compiler->getLdelLength(), -$this->compiler->getRdelLength()), ' $');
|
||||
$attributes = [];
|
||||
if (preg_match('/^(.*)(\s+nocache)$/', $var, $match)) {
|
||||
A = (new \Smarty\Compile\PrintExpressionCompiler())->compile(array('nocache'),$this->compiler,array('value'=>$this->compiler->compileVariable('\''.$match[1].'\'')));
|
||||
} else {
|
||||
A = (new \Smarty\Compile\PrintExpressionCompiler())->compile(array(),$this->compiler,array('value'=>$this->compiler->compileVariable('\''.$var.'\'')));
|
||||
$attributes[] = 'nocache';
|
||||
$var = $match[1];
|
||||
}
|
||||
A = $this->compiler->compilePrintExpression($this->compiler->compileVariable('\''.$var.'\''), $attributes);
|
||||
}
|
||||
|
||||
// simple tag like {name}
|
||||
@@ -321,7 +322,7 @@ smartytag(A)::= SIMPLETAG(B). {
|
||||
if ($this->security) {
|
||||
$this->security->isTrustedConstant($tag, $this->compiler);
|
||||
}
|
||||
A = (new \Smarty\Compile\PrintExpressionCompiler())->compile(array(),$this->compiler,array('value'=>$tag));
|
||||
A = $this->compiler->compilePrintExpression($tag);
|
||||
} else {
|
||||
if (preg_match('/^(.*)(\s+nocache)$/', $tag, $match)) {
|
||||
A = $this->compiler->compileTag($match[1],array('\'nocache\''));
|
||||
@@ -336,10 +337,10 @@ smartytag(A) ::= SMARTYBLOCKCHILDPARENT(i). {
|
||||
$j = strrpos(i,'.');
|
||||
if (i[$j+1] == 'c') {
|
||||
// {$smarty.block.child}
|
||||
A = $this->compiler->compileTag('child',array(),array(i));
|
||||
A = $this->compiler->compileChildBlock();
|
||||
} else {
|
||||
// {$smarty.block.parent}
|
||||
A = $this->compiler->compileTag('parent',array(),array(i));
|
||||
A = $this->compiler->compileParentBlock();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -352,7 +353,7 @@ smartytag(A) ::= LDEL tagbody(B) RDEL. {
|
||||
}
|
||||
// output with optional attributes
|
||||
tagbody(A) ::= outattr(B). {
|
||||
A = (new \Smarty\Compile\PrintExpressionCompiler())->compile(B[1],$this->compiler,array('value'=>B[0]));
|
||||
A = $this->compiler->compilePrintExpression(B[0], B[1]);
|
||||
}
|
||||
|
||||
//
|
||||
@@ -392,7 +393,7 @@ tag(res) ::= LDEL ID(i) attributes(a). {
|
||||
if ($this->security) {
|
||||
$this->security->isTrustedConstant(i, $this->compiler);
|
||||
}
|
||||
res = (new \Smarty\Compile\PrintExpressionCompiler())->compile(a,$this->compiler,array('value'=>i));
|
||||
res = $this->compiler->compilePrintExpression(i, a);
|
||||
} else {
|
||||
res = $this->compiler->compileTag(i,a);
|
||||
}
|
||||
@@ -402,7 +403,7 @@ tag(res) ::= LDEL ID(i). {
|
||||
if ($this->security) {
|
||||
$this->security->isTrustedConstant(i, $this->compiler);
|
||||
}
|
||||
res = (new \Smarty\Compile\PrintExpressionCompiler())->compile(array(),$this->compiler,array('value'=>i));
|
||||
res = $this->compiler->compilePrintExpression(i);
|
||||
} else {
|
||||
res = $this->compiler->compileTag(i,array());
|
||||
}
|
||||
@@ -415,7 +416,7 @@ tag(res) ::= LDEL ID(i) modifierlist(l)attributes(a). {
|
||||
if ($this->security) {
|
||||
$this->security->isTrustedConstant(i, $this->compiler);
|
||||
}
|
||||
res = (new \Smarty\Compile\PrintExpressionCompiler())->compile(a,$this->compiler,array('value'=>i, 'modifierlist'=>l));
|
||||
res = $this->compiler->compilePrintExpression(i, a, l);
|
||||
} else {
|
||||
res = $this->compiler->compileTag(i,a, array('modifierlist'=>l));
|
||||
}
|
||||
|
@@ -222,11 +222,11 @@ class InheritanceRuntime {
|
||||
* @return null|string block content
|
||||
* @throws Exception
|
||||
*/
|
||||
public function callParent(Template $tpl, \Smarty\Runtime\Block $block, $tag) {
|
||||
public function callParent(Template $tpl, \Smarty\Runtime\Block $block) {
|
||||
if (isset($block->parent)) {
|
||||
$this->callBlock($block->parent, $tpl);
|
||||
} else {
|
||||
throw new Exception("inheritance: illegal '{$tag}' used in child template '" .
|
||||
throw new Exception("inheritance: illegal '{\$smarty.block.parent}' used in child template '" .
|
||||
"{$tpl->getInheritance()->sources[$block->tplIndex]->filepath}' block '{$block->name}'");
|
||||
}
|
||||
}
|
||||
|
@@ -1343,7 +1343,7 @@ class CompileBlockExtendsTest extends PHPUnit_Smarty
|
||||
"blockNocache - {$file}");
|
||||
}
|
||||
/*
|
||||
* Data provider für TestBlockNocache
|
||||
* Data provider for TestBlockNocache
|
||||
*/
|
||||
public function dataTestBlockNocache()
|
||||
{
|
||||
|
Reference in New Issue
Block a user