mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-05 02:44:27 +02:00
- bugfix and enhancement
Because several recent problems with template inheritance the {block} tag compiler has been rewriten - Error messages shown now the correct child template file and line number - The compiler could fail on some larger UTF-8 text block (forum topic 24455} - The {strip} tag can now be placed outside {block} tags in child templates (forum topic 24289} - change SmartyException::$escape is now false by default - change PHP traceback has been remove for SmartyException and SmartyCompilerException
This commit is contained in:
@@ -1,4 +1,13 @@
|
|||||||
===== trunk =====
|
===== trunk =====
|
||||||
|
24.08.2013
|
||||||
|
- bugfix and enhancement
|
||||||
|
Because several recent problems with template inheritance the {block} tag compiler has been rewriten
|
||||||
|
- Error messages shown now the correct child template file and line number
|
||||||
|
- The compiler could fail on some larger UTF-8 text block (forum topic 24455}
|
||||||
|
- The {strip} tag can now be placed outside {block} tags in child templates (forum topic 24289}
|
||||||
|
- change SmartyException::$escape is now false by default
|
||||||
|
- change PHP traceback has been remove for SmartyException and SmartyCompilerException
|
||||||
|
|
||||||
14.08.2013
|
14.08.2013
|
||||||
- bugfix compiled filepath of config file did not observe different config_dir (forum topic 24493)
|
- bugfix compiled filepath of config file did not observe different config_dir (forum topic 24493)
|
||||||
|
|
||||||
|
@@ -1510,10 +1510,11 @@ if (Smarty::$_CHARSET !== 'UTF-8') {
|
|||||||
*/
|
*/
|
||||||
class SmartyException extends Exception
|
class SmartyException extends Exception
|
||||||
{
|
{
|
||||||
public static $escape = true;
|
public static $escape = false;
|
||||||
public function __construct($message)
|
|
||||||
|
public function __toString()
|
||||||
{
|
{
|
||||||
$this->message = self::$escape ? htmlentities($message) : $message;
|
return ' --> Smarty: ' . (self::$escape ? htmlentities($this->message) : $this->message) . ' <-- ';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1523,6 +1524,11 @@ class SmartyException extends Exception
|
|||||||
*/
|
*/
|
||||||
class SmartyCompilerException extends SmartyException
|
class SmartyCompilerException extends SmartyException
|
||||||
{
|
{
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return ' --> Smarty Compiler: ' . $this->message . ' <-- ';
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -18,6 +18,8 @@
|
|||||||
*/
|
*/
|
||||||
class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
|
class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
|
||||||
{
|
{
|
||||||
|
|
||||||
|
const parent = '____SMARTY_BLOCK_PARENT____';
|
||||||
/**
|
/**
|
||||||
* Attribute definition: Overwrites base class.
|
* Attribute definition: Overwrites base class.
|
||||||
*
|
*
|
||||||
@@ -32,7 +34,7 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
|
|||||||
* @var array
|
* @var array
|
||||||
* @see Smarty_Internal_CompileBase
|
* @see Smarty_Internal_CompileBase
|
||||||
*/
|
*/
|
||||||
public $shorttag_order = array('name', 'hide');
|
public $shorttag_order = array('name');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Attribute definition: Overwrites base class.
|
* Attribute definition: Overwrites base class.
|
||||||
@@ -40,7 +42,28 @@ 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('hide');
|
public $option_flags = array('hide', 'append', 'prepend', 'nocache');
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute definition: Overwrites base class.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @see Smarty_Internal_CompileBase
|
||||||
|
*/
|
||||||
|
public $optional_attributes = array('internal_file', 'internal_uid', 'internal_line');
|
||||||
|
/**
|
||||||
|
* nested child block names
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $nested_block_names = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* child block source buffer
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $block_data = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiles code for the {block} tag
|
* Compiles code for the {block} tag
|
||||||
@@ -53,15 +76,37 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
|
|||||||
{
|
{
|
||||||
// check and get attributes
|
// check and get attributes
|
||||||
$_attr = $this->getAttributes($compiler, $args);
|
$_attr = $this->getAttributes($compiler, $args);
|
||||||
$save = array($_attr, $compiler->parser->current_buffer, $compiler->nocache, $compiler->smarty->merge_compiled_includes, $compiler->merged_templates, $compiler->smarty->merged_templates_func, $compiler->template->properties, $compiler->template->has_nocache_code);
|
$_name = trim($_attr['name'], "\"'");
|
||||||
$this->openTag($compiler, 'block', $save);
|
|
||||||
if ($_attr['nocache'] == true) {
|
// check if we process an inheritance child template
|
||||||
$compiler->nocache = true;
|
if ($compiler->inheritance_child) {
|
||||||
|
array_unshift(self::$nested_block_names, $_name);
|
||||||
|
$this->template->block_data[$_name]['source'] = '';
|
||||||
|
// build {block} for child block
|
||||||
|
self::$block_data[$_name]['source'] =
|
||||||
|
"{$compiler->smarty->left_delimiter}private_child_block name={$_attr['name']} file='{$compiler->template->source->filepath}'" .
|
||||||
|
" uid='{$compiler->template->source->uid}' line={$compiler->lex->line}";
|
||||||
|
if ($_attr['nocache']) {
|
||||||
|
self::$block_data[$_name]['source'] .= ' nocache';
|
||||||
|
}
|
||||||
|
self::$block_data[$_name]['source'] .= $compiler->smarty->right_delimiter;
|
||||||
|
|
||||||
|
$save = array($_attr, $compiler->inheritance);
|
||||||
|
$this->openTag($compiler, 'block', $save);
|
||||||
|
// set flag for {block} tag
|
||||||
|
$compiler->inheritance = true;
|
||||||
|
$compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
|
||||||
|
$compiler->has_code = false;
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
// set flag for {block} tag
|
|
||||||
$compiler->inheritance = true;
|
|
||||||
// must merge includes
|
// must merge includes
|
||||||
$compiler->smarty->merge_compiled_includes = true;
|
if ($_attr['nocache'] == true) {
|
||||||
|
$compiler->tag_nocache = true;
|
||||||
|
}
|
||||||
|
$save = array($_attr, $compiler->inheritance, $compiler->parser->current_buffer, $compiler->nocache);
|
||||||
|
$this->openTag($compiler, 'block', $save);
|
||||||
|
$compiler->inheritance = true;
|
||||||
|
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
||||||
|
|
||||||
$compiler->parser->current_buffer = new _smarty_template_buffer($compiler->parser);
|
$compiler->parser->current_buffer = new _smarty_template_buffer($compiler->parser);
|
||||||
$compiler->has_code = false;
|
$compiler->has_code = false;
|
||||||
@@ -69,167 +114,69 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Save or replace child block source by block name during parsing
|
|
||||||
*
|
|
||||||
* @param string $block_content block source content
|
|
||||||
* @param string $block_tag opening block tag
|
|
||||||
* @param object $template template object
|
|
||||||
* @param string $filepath filepath of template source
|
|
||||||
*/
|
|
||||||
static function saveBlockData($block_content, $block_tag, $template, $filepath)
|
|
||||||
{
|
|
||||||
$nesting = array();
|
|
||||||
$hide_level = 0;
|
|
||||||
$child_flag = false;
|
|
||||||
$_rdl = preg_quote($template->smarty->right_delimiter);
|
|
||||||
$_ldl = preg_quote($template->smarty->left_delimiter);
|
|
||||||
if (!$template->smarty->auto_literal) {
|
|
||||||
$al = '\s*';
|
|
||||||
} else {
|
|
||||||
$al = '';
|
|
||||||
}
|
|
||||||
if (0 == preg_match("!({$_ldl}{$al}block\s+)(name=)?(\w+|'.*'|\".*\")(\s*?)?((append|prepend|nocache)?(\s*)?(hide)?)?(\s*{$_rdl})!", $block_tag, $_match)) {
|
|
||||||
$error_text = 'Syntax Error in template "' . $template->source->filepath . '" "' . $block_tag . '" illegal options';
|
|
||||||
throw new SmartyCompilerException($error_text);
|
|
||||||
} else {
|
|
||||||
$_name = trim($_match[3], '\'"');
|
|
||||||
// replace {$smarty.block.child}
|
|
||||||
// get nested block tags
|
|
||||||
preg_match_all("%({$_ldl}{$al}block\s+)(name=)?(\w+|'.*?'|\".*?\")([\s\S]*?)(hide)?(\s*{$_rdl})|({$_ldl}{$al}/block\s*{$_rdl})|({$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl})|({$_ldl}|{$_rdl})|([\s\S]*?(?=({$_ldl}|{$_rdl})))%", $block_tag . $block_content . "{$template->smarty->left_delimiter}/block{$template->smarty->right_delimiter}", $_match2);
|
|
||||||
$block_content = '';
|
|
||||||
foreach ($_match2[0] as $key => $text) {
|
|
||||||
// {block} tag
|
|
||||||
if (!empty($_match2[3][$key])) {
|
|
||||||
$name = trim($_match2[3][$key], '\'"');
|
|
||||||
array_push($nesting, array($name, $block_content, $child_flag));
|
|
||||||
$block_content = '';
|
|
||||||
// hide option
|
|
||||||
if (!empty($_match2[5][$key]) && $hide_level == 0 && !isset($template->block_data[$name])) {
|
|
||||||
$hide_level = count($nesting);
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// {/block} tag
|
|
||||||
if (!empty($_match2[7][$key])) {
|
|
||||||
list($name, $content, $cf) = array_pop($nesting);
|
|
||||||
if (isset($template->block_data[$name]) && !$child_flag) {
|
|
||||||
if ($template->block_data[$name]['mode'] == 'prepend') {
|
|
||||||
$block_content = $content . $template->block_data[$name]['source'] . $block_content;
|
|
||||||
} elseif ($template->block_data[$name]['mode'] == 'append') {
|
|
||||||
$block_content = $content . $block_content . $template->block_data[$name]['source'];
|
|
||||||
} else {
|
|
||||||
// check if {$smarty.block.parent} will be later replaced
|
|
||||||
if (strpos($template->block_data[$name]['source'], '%%%%SMARTY_PARENT%%%%') === false) {
|
|
||||||
$block_content = $content . $template->block_data[$name]['source'];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$block_content = $content . $block_content;
|
|
||||||
$cf = true;
|
|
||||||
}
|
|
||||||
$child_flag = $cf;
|
|
||||||
if (count($nesting) < $hide_level) {
|
|
||||||
$hide_level = 0;
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// hide option active
|
|
||||||
if ($hide_level && $hide_level <= count($nesting)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
// {$smarty.block.child} tag
|
|
||||||
if (!empty($_match2[8][$key])) {
|
|
||||||
list($name, $content, $cf) = end($nesting);
|
|
||||||
if (isset($template->block_data[$name])) {
|
|
||||||
$child_flag = true;
|
|
||||||
$block_content .= $template->block_data[$name]['source'];
|
|
||||||
}
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
$block_content .= $_match2[0][$key];
|
|
||||||
|
|
||||||
}
|
|
||||||
// $block_content = preg_replace_callback("%({$_ldl}{$al}block\s+)(name=)?(\w+|'.*?'|\".*?\")([\s\S]*?)(hide)?(\s*{$_rdl})|({$_ldl}{$al}/block\s*{$_rdl})|({$_ldl}{$al}\\\$smarty\.block\.child\s*{$_rdl})|({$_ldl}|{$_rdl})|([\s\S]*?(?=({$_ldl}|{$_rdl})))%", array('Smarty_Internal_Compile_Block', 'replaceBlockChild'), $block_tag.$block_content."{$template->smarty->left_delimiter}/block{$template->smarty->right_delimiter}");
|
|
||||||
if (isset($template->block_data[$_name])) {
|
|
||||||
if (strpos($template->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) {
|
|
||||||
$template->block_data[$_name]['source'] =
|
|
||||||
str_replace('%%%%SMARTY_PARENT%%%%', $block_content, $template->block_data[$_name]['source']);
|
|
||||||
} elseif ($template->block_data[$_name]['mode'] == 'prepend') {
|
|
||||||
$template->block_data[$_name]['source'] .= $block_content;
|
|
||||||
} elseif ($template->block_data[$_name]['mode'] == 'append') {
|
|
||||||
$template->block_data[$_name]['source'] = $block_content . $template->block_data[$_name]['source'];
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$template->block_data[$_name]['source'] = $block_content;
|
|
||||||
$template->block_data[$_name]['file'] = $filepath;
|
|
||||||
}
|
|
||||||
if ($child_flag) {
|
|
||||||
$template->block_data[$_name]['source'] = $block_content;
|
|
||||||
$template->block_data[$_name]['file'] = $filepath;
|
|
||||||
}
|
|
||||||
if ($_match[6] == 'append') {
|
|
||||||
$template->block_data[$_name]['mode'] = 'append';
|
|
||||||
} elseif ($_match[6] == 'prepend') {
|
|
||||||
$template->block_data[$_name]['mode'] = 'prepend';
|
|
||||||
} else {
|
|
||||||
$template->block_data[$_name]['mode'] = 'replace';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compile saved child block source
|
* Compile saved child block source
|
||||||
*
|
*
|
||||||
* @param object $compiler compiler object
|
* @param object $compiler compiler object
|
||||||
* @param string $_name optional name of child block
|
* @param string $_name optional name of child block
|
||||||
* @return string compiled code of schild block
|
* @return string compiled code of child block
|
||||||
*/
|
*/
|
||||||
static function compileChildBlock($compiler, $_name = null)
|
static function compileChildBlock($compiler, $_name = null)
|
||||||
{
|
{
|
||||||
$_output = '';
|
if ($compiler->inheritance_child) {
|
||||||
|
$name1 = Smarty_Internal_Compile_Block::$nested_block_names[0];
|
||||||
|
if (isset($compiler->template->block_data[$name1])) {
|
||||||
|
// replace inner block name with generic
|
||||||
|
Smarty_Internal_Compile_Block::$block_data[$name1]['source'] .= $compiler->template->block_data[$name1]['source'];
|
||||||
|
Smarty_Internal_Compile_Block::$block_data[$name1]['child'] = true;
|
||||||
|
}
|
||||||
|
$compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
|
||||||
|
$compiler->has_code = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
// if called by {$smarty.block.child} we must search the name of enclosing {block}
|
// if called by {$smarty.block.child} we must search the name of enclosing {block}
|
||||||
if ($_name == null) {
|
if ($_name == null) {
|
||||||
$stack_count = count($compiler->_tag_stack);
|
$stack_count = count($compiler->_tag_stack);
|
||||||
while (--$stack_count >= 0) {
|
while (--$stack_count >= 0) {
|
||||||
if ($compiler->_tag_stack[$stack_count][0] == 'block') {
|
if ($compiler->_tag_stack[$stack_count][0] == 'block') {
|
||||||
$_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'], "'\"");
|
$_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'], "\"'");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// flag that child is already compile by {$smarty.block.child} inclusion
|
|
||||||
$compiler->template->block_data[$_name]['compiled'] = true;
|
|
||||||
}
|
}
|
||||||
if ($_name == null) {
|
if ($_name == null) {
|
||||||
$compiler->trigger_template_error('{$smarty.block.child} used out of context', $compiler->lex->taglineno);
|
$compiler->trigger_template_error(' tag {$smarty.block.child} used outside {block} tags ', $compiler->lex->taglineno);
|
||||||
}
|
}
|
||||||
// undefined child?
|
// undefined child?
|
||||||
if (!isset($compiler->template->block_data[$_name]['source'])) {
|
if (!isset($compiler->template->block_data[$_name]['source'])) {
|
||||||
|
$compiler->popTrace();
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
// flag that child is already compile by {$smarty.block.child} inclusion
|
||||||
|
$compiler->template->block_data[$_name]['compiled'] = true;
|
||||||
$_tpl = new Smarty_Internal_template('string:' . $compiler->template->block_data[$_name]['source'], $compiler->smarty, $compiler->template, $compiler->template->cache_id,
|
$_tpl = new Smarty_Internal_template('string:' . $compiler->template->block_data[$_name]['source'], $compiler->smarty, $compiler->template, $compiler->template->cache_id,
|
||||||
$compiler->template->compile_id, $compiler->template->caching, $compiler->template->cache_lifetime);
|
$compiler->template->compile_id, $compiler->template->caching, $compiler->template->cache_lifetime);
|
||||||
|
if ($compiler->smarty->debugging) {
|
||||||
|
Smarty_Internal_Debug::ignore($_tpl);
|
||||||
|
}
|
||||||
$_tpl->variable_filters = $compiler->template->variable_filters;
|
$_tpl->variable_filters = $compiler->template->variable_filters;
|
||||||
$_tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
|
$_tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
|
||||||
$_tpl->source->filepath = $compiler->template->block_data[$_name]['file'];
|
|
||||||
$_tpl->allow_relative_path = true;
|
$_tpl->allow_relative_path = true;
|
||||||
if ($compiler->nocache) {
|
$_tpl->compiler->inheritance = true;
|
||||||
$_tpl->compiler->forceNocache = 2;
|
|
||||||
} else {
|
|
||||||
$_tpl->compiler->forceNocache = 1;
|
|
||||||
}
|
|
||||||
$_tpl->compiler->suppressHeader = true;
|
$_tpl->compiler->suppressHeader = true;
|
||||||
$_tpl->compiler->suppressFilter = true;
|
$_tpl->compiler->suppressFilter = true;
|
||||||
$_tpl->compiler->suppressTemplatePropertyHeader = true;
|
$_tpl->compiler->suppressTemplatePropertyHeader = true;
|
||||||
$_tpl->compiler->suppressMergedTemplates = true;
|
$_tpl->compiler->suppressMergedTemplates = true;
|
||||||
if (strpos($compiler->template->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) {
|
$nocache = $compiler->nocache || $compiler->tag_nocache;
|
||||||
$_output = str_replace('%%%%SMARTY_PARENT%%%%', $compiler->parser->current_buffer->to_smarty_php(), $_tpl->compiler->compileTemplate($_tpl));
|
if (strpos($compiler->template->block_data[$_name]['source'], self::parent) !== false) {
|
||||||
|
$_output = str_replace(self::parent, $compiler->parser->current_buffer->to_smarty_php(), $_tpl->compiler->compileTemplate($_tpl, $nocache));
|
||||||
} elseif ($compiler->template->block_data[$_name]['mode'] == 'prepend') {
|
} elseif ($compiler->template->block_data[$_name]['mode'] == 'prepend') {
|
||||||
$_output = $_tpl->compiler->compileTemplate($_tpl) . $compiler->parser->current_buffer->to_smarty_php();
|
$_output = $_tpl->compiler->compileTemplate($_tpl, $nocache) . $compiler->parser->current_buffer->to_smarty_php();
|
||||||
} elseif ($compiler->template->block_data[$_name]['mode'] == 'append') {
|
} elseif ($compiler->template->block_data[$_name]['mode'] == 'append') {
|
||||||
$_output = $compiler->parser->current_buffer->to_smarty_php() . $_tpl->compiler->compileTemplate($_tpl);
|
$_output = $compiler->parser->current_buffer->to_smarty_php() . $_tpl->compiler->compileTemplate($_tpl, $nocache);
|
||||||
} elseif (!empty($compiler->template->block_data[$_name])) {
|
} elseif (!empty($compiler->template->block_data[$_name])) {
|
||||||
$_output = $_tpl->compiler->compileTemplate($_tpl);
|
$_output = $_tpl->compiler->compileTemplate($_tpl, $nocache);
|
||||||
}
|
}
|
||||||
$compiler->template->properties['file_dependency'] = array_merge($compiler->template->properties['file_dependency'], $_tpl->properties['file_dependency']);
|
$compiler->template->properties['file_dependency'] = array_merge($compiler->template->properties['file_dependency'], $_tpl->properties['file_dependency']);
|
||||||
$compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $_tpl->properties['function']);
|
$compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $_tpl->properties['function']);
|
||||||
@@ -251,12 +198,55 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
unset($_tpl);
|
unset($_tpl);
|
||||||
|
$compiler->has_code = true;
|
||||||
return $_output;
|
return $_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compile $smarty.block.parent
|
||||||
|
*
|
||||||
|
* @param object $compiler compiler object
|
||||||
|
* @param string $_name optional name of child block
|
||||||
|
* @return string compiled code of schild block
|
||||||
|
*/
|
||||||
|
static function compileParentBlock($compiler, $_name = null)
|
||||||
|
{
|
||||||
|
// if called by {$smarty.block.parent} we must search the name of enclosing {block}
|
||||||
|
if ($_name == null) {
|
||||||
|
$stack_count = count($compiler->_tag_stack);
|
||||||
|
while (--$stack_count >= 0) {
|
||||||
|
if ($compiler->_tag_stack[$stack_count][0] == 'block') {
|
||||||
|
$_name = trim($compiler->_tag_stack[$stack_count][1][0]['name'], "\"'");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($_name == null) {
|
||||||
|
$compiler->trigger_template_error(' tag {$smarty.block.parent} used outside {block} tags ', $compiler->lex->taglineno);
|
||||||
|
}
|
||||||
|
if (empty(Smarty_Internal_Compile_Block::$nested_block_names)) {
|
||||||
|
$compiler->trigger_template_error(' illegal {$smarty.block.parent} in parent template ', $compiler->lex->taglineno);
|
||||||
|
}
|
||||||
|
Smarty_Internal_Compile_Block::$block_data[Smarty_Internal_Compile_Block::$nested_block_names[0]]['source'] .= Smarty_Internal_Compile_Block::parent;
|
||||||
|
$compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
|
||||||
|
$compiler->has_code = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Process block source
|
||||||
|
*
|
||||||
|
* @param string $source source text
|
||||||
|
* @return ''
|
||||||
|
*/
|
||||||
|
static function blockSource($compiler, $source)
|
||||||
|
{
|
||||||
|
Smarty_Internal_Compile_Block::$block_data[Smarty_Internal_Compile_Block::$nested_block_names[0]]['source'] .= $source;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Smarty Internal Plugin Compile BlockClose Class
|
* Smarty Internal Plugin Compile BlockClose Class
|
||||||
*
|
*
|
||||||
@@ -279,19 +269,63 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase
|
|||||||
$_attr = $this->getAttributes($compiler, $args);
|
$_attr = $this->getAttributes($compiler, $args);
|
||||||
$saved_data = $this->closeTag($compiler, array('block'));
|
$saved_data = $this->closeTag($compiler, array('block'));
|
||||||
$_name = trim($saved_data[0]['name'], "\"'");
|
$_name = trim($saved_data[0]['name'], "\"'");
|
||||||
|
// reset flag for {block} tag
|
||||||
|
$compiler->inheritance = $saved_data[1];
|
||||||
|
// check if we process an inheritance child template
|
||||||
|
if ($compiler->inheritance_child) {
|
||||||
|
$name1 = Smarty_Internal_Compile_Block::$nested_block_names[0];
|
||||||
|
Smarty_Internal_Compile_Block::$block_data[$name1]['source'] .= "{$compiler->smarty->left_delimiter}/private_child_block{$compiler->smarty->right_delimiter}";
|
||||||
|
$level = count(Smarty_Internal_Compile_Block::$nested_block_names);
|
||||||
|
array_shift(Smarty_Internal_Compile_Block::$nested_block_names);
|
||||||
|
if (!empty(Smarty_Internal_Compile_Block::$nested_block_names)) {
|
||||||
|
$name2 = Smarty_Internal_Compile_Block::$nested_block_names[0];
|
||||||
|
if (isset($compiler->template->block_data[$name1]) || !$saved_data[0]['hide']) {
|
||||||
|
if (isset(Smarty_Internal_Compile_Block::$block_data[$name1]['child']) || !isset($compiler->template->block_data[$name1])) {
|
||||||
|
Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
|
||||||
|
} else {
|
||||||
|
if ($compiler->template->block_data[$name1]['mode'] == 'append') {
|
||||||
|
Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= Smarty_Internal_Compile_Block::$block_data[$name1]['source'] . $compiler->template->block_data[$name1]['source'];
|
||||||
|
} elseif ($compiler->template->block_data[$name1]['mode'] == 'prepend') {
|
||||||
|
Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= $compiler->template->block_data[$name1]['source'] . Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
|
||||||
|
} else {
|
||||||
|
Smarty_Internal_Compile_Block::$block_data[$name2]['source'] .= $compiler->template->block_data[$name1]['source'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset(Smarty_Internal_Compile_Block::$block_data[$name1]);
|
||||||
|
$compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBLOCK);
|
||||||
|
} else {
|
||||||
|
if (isset($compiler->template->block_data[$name1]) || !$saved_data[0]['hide']) {
|
||||||
|
if (isset($compiler->template->block_data[$name1]) && !isset(Smarty_Internal_Compile_Block::$block_data[$name1]['child'])) {
|
||||||
|
if (strpos($compiler->template->block_data[$name1]['source'], Smarty_Internal_Compile_Block::parent) !== false) {
|
||||||
|
$compiler->template->block_data[$name1]['source'] =
|
||||||
|
str_replace(Smarty_Internal_Compile_Block::parent, Smarty_Internal_Compile_Block::$block_data[$name1]['source'], $compiler->template->block_data[$name1]['source']);
|
||||||
|
} elseif ($compiler->template->block_data[$name1]['mode'] == 'prepend') {
|
||||||
|
$compiler->template->block_data[$name1]['source'] .= Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
|
||||||
|
} elseif ($compiler->template->block_data[$name1]['mode'] == 'append') {
|
||||||
|
$compiler->template->block_data[$name1]['source'] = Smarty_Internal_Compile_Block::$block_data[$name1]['source'] . $compiler->template->block_data[$name1]['source'];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$compiler->template->block_data[$name1]['source'] = Smarty_Internal_Compile_Block::$block_data[$name1]['source'];
|
||||||
|
}
|
||||||
|
$compiler->template->block_data[$name1]['mode'] = 'replace';
|
||||||
|
if ($saved_data[0]['append']) {
|
||||||
|
$compiler->template->block_data[$name1]['mode'] = 'append';
|
||||||
|
}
|
||||||
|
if ($saved_data[0]['prepend']) {
|
||||||
|
$compiler->template->block_data[$name1]['mode'] = 'prepend';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset(Smarty_Internal_Compile_Block::$block_data[$name1]);
|
||||||
|
$compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBODY);
|
||||||
|
}
|
||||||
|
$compiler->has_code = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (isset($compiler->template->block_data[$_name]) && !isset($compiler->template->block_data[$_name]['compiled'])) {
|
if (isset($compiler->template->block_data[$_name]) && !isset($compiler->template->block_data[$_name]['compiled'])) {
|
||||||
// restore to status before {block} tag as new subtemplate code of parent {block} is not needed
|
|
||||||
// TODO: Below code was disabled in 3.1.8 because of problems with {include} in nested {block} tags in child templates
|
|
||||||
// combined with append/prepend or $smarty.block.parent
|
|
||||||
// For later versions it should be checked under which conditions it could run for optimisation
|
|
||||||
//
|
|
||||||
//$compiler->merged_templates = $saved_data[4];
|
|
||||||
//$compiler->smarty->merged_templates_func = $saved_data[5];
|
|
||||||
//$compiler->template->properties = $saved_data[6];
|
|
||||||
//$compiler->template->has_nocache_code = $saved_data[7];
|
|
||||||
$_output = Smarty_Internal_Compile_Block::compileChildBlock($compiler, $_name);
|
$_output = Smarty_Internal_Compile_Block::compileChildBlock($compiler, $_name);
|
||||||
} else {
|
} else {
|
||||||
if (isset($saved_data[0]['hide']) && !isset($compiler->template->block_data[$_name]['source'])) {
|
if ($saved_data[0]['hide'] && !isset($compiler->template->block_data[$_name]['source'])) {
|
||||||
$_output = '';
|
$_output = '';
|
||||||
} else {
|
} else {
|
||||||
$_output = $compiler->parser->current_buffer->to_smarty_php();
|
$_output = $compiler->parser->current_buffer->to_smarty_php();
|
||||||
@@ -299,15 +333,96 @@ class Smarty_Internal_Compile_Blockclose extends Smarty_Internal_CompileBase
|
|||||||
unset($compiler->template->block_data[$_name]['compiled']);
|
unset($compiler->template->block_data[$_name]['compiled']);
|
||||||
}
|
}
|
||||||
// reset flags
|
// reset flags
|
||||||
$compiler->parser->current_buffer = $saved_data[1];
|
$compiler->parser->current_buffer = $saved_data[2];
|
||||||
$compiler->nocache = $saved_data[2];
|
if ($compiler->nocache) {
|
||||||
$compiler->smarty->merge_compiled_includes = $saved_data[3];
|
$compiler->tag_nocache = true;
|
||||||
// reset flag for {block} tag
|
}
|
||||||
$compiler->inheritance = false;
|
$compiler->nocache = $saved_data[3];
|
||||||
// $_output content has already nocache code processed
|
// $_output content has already nocache code processed
|
||||||
$compiler->suppressNocacheProcessing = true;
|
$compiler->suppressNocacheProcessing = true;
|
||||||
|
|
||||||
return $_output;
|
return $_output;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty Internal Plugin Compile Child Block Class
|
||||||
|
*
|
||||||
|
* @package Smarty
|
||||||
|
* @subpackage Compiler
|
||||||
|
*/
|
||||||
|
class Smarty_Internal_Compile_Private_Child_Block extends Smarty_Internal_CompileBase
|
||||||
|
{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Attribute definition: Overwrites base class.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
* @see Smarty_Internal_CompileBase
|
||||||
|
*/
|
||||||
|
public $required_attributes = array('name', 'file', 'uid', 'line');
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiles code for the {private_child_block} tag
|
||||||
|
*
|
||||||
|
* @param array $args array with attributes from parser
|
||||||
|
* @param object $compiler compiler object
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
public function compile($args, $compiler)
|
||||||
|
{
|
||||||
|
// check and get attributes
|
||||||
|
$_attr = $this->getAttributes($compiler, $args);
|
||||||
|
|
||||||
|
// must merge includes
|
||||||
|
if ($_attr['nocache'] == true) {
|
||||||
|
$compiler->tag_nocache = true;
|
||||||
|
}
|
||||||
|
$save = array($_attr, $compiler->nocache);
|
||||||
|
|
||||||
|
// set trace back to child block
|
||||||
|
$compiler->pushTrace(trim($_attr['file'], "\"'"), trim($_attr['uid'], "\"'"), $_attr['line'] - $compiler->lex->line);
|
||||||
|
|
||||||
|
$this->openTag($compiler, 'private_child_block', $save);
|
||||||
|
|
||||||
|
$compiler->nocache = $compiler->nocache | $compiler->tag_nocache;
|
||||||
|
$compiler->has_code = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Smarty Internal Plugin Compile Child Block Close Class
|
||||||
|
*
|
||||||
|
* @package Smarty
|
||||||
|
* @subpackage Compiler
|
||||||
|
*/
|
||||||
|
class Smarty_Internal_Compile_Private_Child_Blockclose extends Smarty_Internal_CompileBase
|
||||||
|
{
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compiles code for the {/private_child_block} tag
|
||||||
|
*
|
||||||
|
* @param array $args array with attributes from parser
|
||||||
|
* @param object $compiler compiler object
|
||||||
|
* @return boolean true
|
||||||
|
*/
|
||||||
|
public function compile($args, $compiler)
|
||||||
|
{
|
||||||
|
// check and get attributes
|
||||||
|
$_attr = $this->getAttributes($compiler, $args);
|
||||||
|
|
||||||
|
$saved_data = $this->closeTag($compiler, array('private_child_block'));
|
||||||
|
|
||||||
|
// end of child block
|
||||||
|
$compiler->popTrace();
|
||||||
|
|
||||||
|
$compiler->nocache = $saved_data[1];
|
||||||
|
$compiler->has_code = false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@@ -68,7 +68,6 @@ class Smarty_Internal_Compile_Break extends Smarty_Internal_CompileBase
|
|||||||
if ($level_count != 0) {
|
if ($level_count != 0) {
|
||||||
$compiler->trigger_template_error("cannot break {$_levels} level(s)", $compiler->lex->taglineno);
|
$compiler->trigger_template_error("cannot break {$_levels} level(s)", $compiler->lex->taglineno);
|
||||||
}
|
}
|
||||||
$compiler->has_code = true;
|
|
||||||
|
|
||||||
return "<?php break {$_levels}?>";
|
return "<?php break {$_levels}?>";
|
||||||
}
|
}
|
||||||
|
@@ -69,7 +69,6 @@ class Smarty_Internal_Compile_Continue extends Smarty_Internal_CompileBase
|
|||||||
if ($level_count != 0) {
|
if ($level_count != 0) {
|
||||||
$compiler->trigger_template_error("cannot continue {$_levels} level(s)", $compiler->lex->taglineno);
|
$compiler->trigger_template_error("cannot continue {$_levels} level(s)", $compiler->lex->taglineno);
|
||||||
}
|
}
|
||||||
$compiler->has_code = true;
|
|
||||||
|
|
||||||
return "<?php continue {$_levels}?>";
|
return "<?php continue {$_levels}?>";
|
||||||
}
|
}
|
||||||
|
@@ -1,132 +1,87 @@
|
|||||||
<?php
|
<?php
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Smarty Internal Plugin Compile extend
|
* Smarty Internal Plugin Compile extend
|
||||||
*
|
*
|
||||||
* Compiles the {extends} tag
|
* Compiles the {extends} tag
|
||||||
*
|
*
|
||||||
* @package Smarty
|
* @package Smarty
|
||||||
* @subpackage Compiler
|
* @subpackage Compiler
|
||||||
* @author Uwe Tews
|
* @author Uwe Tews
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Smarty Internal Plugin Compile extend Class
|
* Smarty Internal Plugin Compile extend Class
|
||||||
*
|
*
|
||||||
* @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_CompileBase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* Attribute definition: Overwrites base class.
|
* Attribute definition: Overwrites base class.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
* @see Smarty_Internal_CompileBase
|
* @see Smarty_Internal_CompileBase
|
||||||
*/
|
*/
|
||||||
public $required_attributes = array('file');
|
public $required_attributes = array('file');
|
||||||
/**
|
/**
|
||||||
* Attribute definition: Overwrites base class.
|
* Attribute definition: Overwrites base class.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
* @see Smarty_Internal_CompileBase
|
* @see Smarty_Internal_CompileBase
|
||||||
*/
|
*/
|
||||||
public $shorttag_order = array('file');
|
public $shorttag_order = array('file');
|
||||||
/**
|
|
||||||
* mbstring.overload flag
|
|
||||||
*
|
|
||||||
* @var int
|
|
||||||
*/
|
|
||||||
public $mbstring_overload = 0;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiles code for the {extends} tag
|
* Compiles code for the {extends} tag
|
||||||
*
|
*
|
||||||
* @param array $args array with attributes from parser
|
* @param array $args array with attributes from parser
|
||||||
* @param object $compiler compiler object
|
* @param object $compiler compiler object
|
||||||
* @return string compiled code
|
* @return string compiled code
|
||||||
*/
|
*/
|
||||||
public function compile($args, $compiler)
|
public function compile($args, $compiler)
|
||||||
{
|
{
|
||||||
static $_is_stringy = array('string' => true, 'eval' => true);
|
|
||||||
$this->_rdl = preg_quote($compiler->smarty->right_delimiter);
|
|
||||||
$this->_ldl = preg_quote($compiler->smarty->left_delimiter);
|
|
||||||
if (!$compiler->smarty->auto_literal) {
|
|
||||||
$al = '\s*';
|
|
||||||
} else {
|
|
||||||
$al = '';
|
|
||||||
}
|
|
||||||
$filepath = $compiler->template->source->filepath;
|
|
||||||
$this->mbstring_overload = ini_get('mbstring.func_overload') & 2;
|
|
||||||
// check and get attributes
|
// check and get attributes
|
||||||
$_attr = $this->getAttributes($compiler, $args);
|
$_attr = $this->getAttributes($compiler, $args);
|
||||||
if ($_attr['nocache'] === true) {
|
if ($_attr['nocache'] === true) {
|
||||||
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
|
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
|
||||||
}
|
}
|
||||||
|
|
||||||
$_smarty_tpl = $compiler->template;
|
|
||||||
$include_file = null;
|
|
||||||
if (strpos($_attr['file'], '$_tmp') !== false) {
|
if (strpos($_attr['file'], '$_tmp') !== false) {
|
||||||
$compiler->trigger_template_error('illegal value for file attribute', $compiler->lex->taglineno);
|
$compiler->trigger_template_error('illegal value for file attribute', $compiler->lex->taglineno);
|
||||||
}
|
}
|
||||||
eval('$include_file = ' . $_attr['file'] . ';');
|
// add tag to call parent template at the end of source
|
||||||
// create template object
|
|
||||||
$_template = new $compiler->smarty->template_class($include_file, $compiler->smarty, $compiler->template);
|
|
||||||
// save file dependency
|
|
||||||
if (isset($_is_stringy[$_template->source->type])) {
|
|
||||||
$template_sha1 = sha1($include_file);
|
|
||||||
} else {
|
|
||||||
$template_sha1 = sha1($_template->source->filepath);
|
|
||||||
}
|
|
||||||
if (isset($compiler->template->properties['file_dependency'][$template_sha1])) {
|
|
||||||
$compiler->trigger_template_error("illegal recursive call of \"{$include_file}\"", $compiler->lex->line - 1);
|
|
||||||
}
|
|
||||||
$compiler->template->properties['file_dependency'][$template_sha1] = array($_template->source->filepath, $_template->source->timestamp, $_template->source->type);
|
|
||||||
$_content = ($this->mbstring_overload ? mb_substr($compiler->lex->data, $compiler->lex->counter - 1, 20000000, 'latin1') : substr($compiler->lex->data, $compiler->lex->counter - 1));
|
|
||||||
if (preg_match_all("!({$this->_ldl}{$al}block\s(.+?)\s*{$this->_rdl})!", $_content, $s) !=
|
|
||||||
preg_match_all("!({$this->_ldl}{$al}/block\s*{$this->_rdl})!", $_content, $c)) {
|
|
||||||
$compiler->trigger_template_error('unmatched {block} {/block} pairs');
|
|
||||||
}
|
|
||||||
preg_match_all("!{$this->_ldl}{$al}block\s(.+?)\s*{$this->_rdl}|{$this->_ldl}{$al}/block\s*{$this->_rdl}|{$this->_ldl}\*([\S\s]*?)\*{$this->_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE);
|
|
||||||
$_result_count = count($_result[0]);
|
|
||||||
$_start = 0;
|
|
||||||
while ($_start+1 < $_result_count) {
|
|
||||||
$_end = 0;
|
|
||||||
$_level = 1;
|
|
||||||
if (($this->mbstring_overload ? mb_substr($_result[0][$_start][0],0,mb_strlen($compiler->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start][0],0,strlen($compiler->smarty->left_delimiter)+1)) == $compiler->smarty->left_delimiter.'*') {
|
|
||||||
$_start++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
while ($_level != 0) {
|
|
||||||
$_end++;
|
|
||||||
if (($this->mbstring_overload ? mb_substr($_result[0][$_start + $_end][0],0,mb_strlen($compiler->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start + $_end][0],0,strlen($compiler->smarty->left_delimiter)+1)) == $compiler->smarty->left_delimiter.'*') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strpos($_result[0][$_start + $_end][0], '/')) {
|
|
||||||
$_level++;
|
|
||||||
} else {
|
|
||||||
$_level--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$_block_content = str_replace($compiler->smarty->left_delimiter . '$smarty.block.parent' . $compiler->smarty->right_delimiter, '%%%%SMARTY_PARENT%%%%',
|
|
||||||
($this->mbstring_overload ? mb_substr($_content, $_result[0][$_start][1] + mb_strlen($_result[0][$_start][0], 'latin1'), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + mb_strlen($_result[0][$_start][0], 'latin1'), 'latin1') : substr($_content, $_result[0][$_start][1] + strlen($_result[0][$_start][0]), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + strlen($_result[0][$_start][0]))));
|
|
||||||
Smarty_Internal_Compile_Block::saveBlockData($_block_content, $_result[0][$_start][0], $compiler->template, $filepath);
|
|
||||||
$_start = $_start + $_end + 1;
|
|
||||||
}
|
|
||||||
if ($_template->source->type == 'extends') {
|
|
||||||
$_template->block_data = $compiler->template->block_data;
|
|
||||||
}
|
|
||||||
$compiler->template->source->content = $_template->source->content;
|
|
||||||
if ($_template->source->type == 'extends') {
|
|
||||||
$compiler->template->block_data = $_template->block_data;
|
|
||||||
foreach ($_template->source->components as $key => $component) {
|
|
||||||
$compiler->template->properties['file_dependency'][$key] = array($component->filepath, $component->timestamp, $component->type);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$compiler->template->source->filepath = $_template->source->filepath;
|
|
||||||
$compiler->abort_and_recompile = true;
|
|
||||||
|
|
||||||
|
if ($compiler->has_variable_string || !((substr_count($_attr['file'], '"') == 2 || substr_count($_attr['file'], "'") == 2))
|
||||||
|
|| substr_count($_attr['file'], '(') != 0 || substr_count($_attr['file'], '$_smarty_tpl->') != 0
|
||||||
|
) {
|
||||||
|
$compiler->trigger_template_error('variable template file name not allowed', $compiler->lex->taglineno);
|
||||||
|
}
|
||||||
|
|
||||||
|
$name = trim($_attr['file'],"\"'");
|
||||||
|
// create template object
|
||||||
|
$_template = new $compiler->smarty->template_class($name, $compiler->smarty, $compiler->template);
|
||||||
|
// check for recursion
|
||||||
|
$uid = $_template->source->uid;
|
||||||
|
if (isset($compiler->extends_uid[$uid])) {
|
||||||
|
$compiler->trigger_template_error("illegal recursive call of \"$include_file\"", $this->lex->line - 1);
|
||||||
|
}
|
||||||
|
$compiler->extends_uid[$uid] = true;
|
||||||
|
if (empty($_template->source->components)) {
|
||||||
|
array_unshift($compiler->sources, $_template->source);
|
||||||
|
} else {
|
||||||
|
foreach ($_template->source->components as $source) {
|
||||||
|
array_unshift($compiler->sources, $source);
|
||||||
|
$uid = $source->uid;
|
||||||
|
if (isset($compiler->extends_uid[$uid])) {
|
||||||
|
$compiler->trigger_template_error("illegal recursive call of \"{$sorce->filepath}\"", $this->lex->line - 1);
|
||||||
|
}
|
||||||
|
$compiler->extends_uid[$uid] = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unset ($_template);
|
||||||
|
$compiler->inheritance_child = true;
|
||||||
|
$compiler->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBODY);
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -86,7 +86,6 @@ class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase
|
|||||||
$compiler->template->has_nocache_code = false;
|
$compiler->template->has_nocache_code = false;
|
||||||
$compiler->has_code = false;
|
$compiler->has_code = false;
|
||||||
$compiler->template->properties['function'][$_name]['compiled'] = '';
|
$compiler->template->properties['function'][$_name]['compiled'] = '';
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -1,61 +1,61 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Smarty Internal Plugin Compile Include
|
* Smarty Internal Plugin Compile Include
|
||||||
*
|
*
|
||||||
* Compiles the {include} tag
|
* Compiles the {include} tag
|
||||||
*
|
*
|
||||||
* @package Smarty
|
* @package Smarty
|
||||||
* @subpackage Compiler
|
* @subpackage Compiler
|
||||||
* @author Uwe Tews
|
* @author Uwe Tews
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Smarty Internal Plugin Compile Include Class
|
* Smarty Internal Plugin Compile Include Class
|
||||||
*
|
*
|
||||||
* @package Smarty
|
* @package Smarty
|
||||||
* @subpackage Compiler
|
* @subpackage Compiler
|
||||||
*/
|
*/
|
||||||
class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* caching mode to create nocache code but no cache file
|
* caching mode to create nocache code but no cache file
|
||||||
*/
|
*/
|
||||||
const CACHING_NOCACHE_CODE = 9999;
|
const CACHING_NOCACHE_CODE = 9999;
|
||||||
/**
|
/**
|
||||||
* Attribute definition: Overwrites base class.
|
* Attribute definition: Overwrites base class.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
* @see Smarty_Internal_CompileBase
|
* @see Smarty_Internal_CompileBase
|
||||||
*/
|
*/
|
||||||
public $required_attributes = array('file');
|
public $required_attributes = array('file');
|
||||||
/**
|
/**
|
||||||
* Attribute definition: Overwrites base class.
|
* Attribute definition: Overwrites base class.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
* @see Smarty_Internal_CompileBase
|
* @see Smarty_Internal_CompileBase
|
||||||
*/
|
*/
|
||||||
public $shorttag_order = array('file');
|
public $shorttag_order = array('file');
|
||||||
/**
|
/**
|
||||||
* Attribute definition: Overwrites base class.
|
* Attribute definition: Overwrites base class.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
* @see Smarty_Internal_CompileBase
|
* @see Smarty_Internal_CompileBase
|
||||||
*/
|
*/
|
||||||
public $option_flags = array('nocache', 'inline', 'caching');
|
public $option_flags = array('nocache', 'inline', 'caching');
|
||||||
/**
|
/**
|
||||||
* Attribute definition: Overwrites base class.
|
* Attribute definition: Overwrites base class.
|
||||||
*
|
*
|
||||||
* @var array
|
* @var array
|
||||||
* @see Smarty_Internal_CompileBase
|
* @see Smarty_Internal_CompileBase
|
||||||
*/
|
*/
|
||||||
public $optional_attributes = array('_any');
|
public $optional_attributes = array('_any');
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compiles code for the {include} tag
|
* Compiles code for the {include} tag
|
||||||
*
|
*
|
||||||
* @param array $args array with attributes from parser
|
* @param array $args array with attributes from parser
|
||||||
* @param object $compiler compiler object
|
* @param object $compiler compiler object
|
||||||
* @param array $parameter array with compilation parameter
|
* @param array $parameter array with compilation parameter
|
||||||
* @return string compiled code
|
* @return string compiled code
|
||||||
*/
|
*/
|
||||||
public function compile($args, $compiler, $parameter)
|
public function compile($args, $compiler, $parameter)
|
||||||
@@ -81,12 +81,15 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
|||||||
$_parent_scope = Smarty::SCOPE_GLOBAL;
|
$_parent_scope = Smarty::SCOPE_GLOBAL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
$_caching = 'null';
|
|
||||||
if ($compiler->nocache || $compiler->tag_nocache) {
|
$_caching = Smarty::CACHING_OFF;
|
||||||
$_caching = Smarty::CACHING_OFF;
|
|
||||||
}
|
// flag if included template code should be merged into caller
|
||||||
// default for included templates
|
$merge_compiled_includes = ($compiler->smarty->merge_compiled_includes || $_attr['inline'] === true) && !$compiler->template->source->recompiled;
|
||||||
if ($compiler->template->caching && !$compiler->nocache && !$compiler->tag_nocache) {
|
|
||||||
|
// set default when in nocache mode
|
||||||
|
// if ($compiler->template->caching && ($compiler->nocache || $compiler->tag_nocache || $compiler->forceNocache == 2)) {
|
||||||
|
if ($compiler->template->caching && ((!$compiler->inheritance && !$compiler->nocache && !$compiler->tag_nocache) || ($compiler->inheritance && ($compiler->nocache ||$compiler->tag_nocache)))) {
|
||||||
$_caching = self::CACHING_NOCACHE_CODE;
|
$_caching = self::CACHING_NOCACHE_CODE;
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -118,53 +121,89 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
|||||||
}
|
}
|
||||||
if ($_attr['nocache'] === true) {
|
if ($_attr['nocache'] === true) {
|
||||||
$compiler->tag_nocache = true;
|
$compiler->tag_nocache = true;
|
||||||
|
if ($merge_compiled_includes || $compiler->inheritance) {
|
||||||
|
$_caching = self::CACHING_NOCACHE_CODE;
|
||||||
|
} else {
|
||||||
$_caching = Smarty::CACHING_OFF;
|
$_caching = Smarty::CACHING_OFF;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
$has_compiled_template = false;
|
$has_compiled_template = false;
|
||||||
if (($compiler->smarty->merge_compiled_includes || $_attr['inline'] === true) && !$compiler->template->source->recompiled
|
if ($merge_compiled_includes || $compiler->inheritance) {
|
||||||
&& !($compiler->template->caching && ($compiler->tag_nocache || $compiler->nocache)) && $_caching != Smarty::CACHING_LIFETIME_CURRENT) {
|
// variable template name ?
|
||||||
// check if compiled code can be merged (contains no variable part)
|
if ($compiler->has_variable_string || !((substr_count($include_file, '"') == 2 || substr_count($include_file, "'") == 2))
|
||||||
if (!$compiler->has_variable_string && (substr_count($include_file, '"') == 2 or substr_count($include_file, "'") == 2)
|
|| substr_count($include_file, '(') != 0 || substr_count($include_file, '$_smarty_tpl->') != 0
|
||||||
and substr_count($include_file, '(') == 0 and substr_count($include_file, '$_smarty_tpl->') == 0) {
|
) {
|
||||||
$tpl_name = null;
|
$merge_compiled_includes = false;
|
||||||
eval("\$tpl_name = $include_file;");
|
if ($compiler->inheritance) {
|
||||||
if (!isset($compiler->smarty->merged_templates_func[$tpl_name]) || $compiler->inheritance) {
|
$compiler->trigger_template_error(' variable template file names not allow within {block} tags');
|
||||||
$tpl = new $compiler->smarty->template_class ($tpl_name, $compiler->smarty, $compiler->template, $compiler->template->cache_id, $compiler->template->compile_id);
|
|
||||||
// save unique function name
|
|
||||||
$compiler->smarty->merged_templates_func[$tpl_name]['func'] = $tpl->properties['unifunc'] = 'content_'. str_replace('.', '_', uniqid('', true));
|
|
||||||
// use current nocache hash for inlined code
|
|
||||||
$compiler->smarty->merged_templates_func[$tpl_name]['nocache_hash'] = $tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
|
|
||||||
if ($compiler->template->caching) {
|
|
||||||
// needs code for cached page but no cache file
|
|
||||||
$tpl->caching = self::CACHING_NOCACHE_CODE;
|
|
||||||
}
|
|
||||||
// make sure whole chain gest compiled
|
|
||||||
$tpl->mustCompile = true;
|
|
||||||
if (!($tpl->source->uncompiled) && $tpl->source->exists) {
|
|
||||||
// get compiled code
|
|
||||||
$compiled_code = $tpl->compiler->compileTemplate($tpl);
|
|
||||||
// release compiler object to free memory
|
|
||||||
unset($tpl->compiler);
|
|
||||||
// merge compiled code for {function} tags
|
|
||||||
$compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $tpl->properties['function']);
|
|
||||||
// merge filedependency
|
|
||||||
$tpl->properties['file_dependency'][$tpl->source->uid] = array($tpl->source->filepath, $tpl->source->timestamp,$tpl->source->type);
|
|
||||||
$compiler->template->properties['file_dependency'] = array_merge($compiler->template->properties['file_dependency'], $tpl->properties['file_dependency']);
|
|
||||||
// remove header code
|
|
||||||
$compiled_code = preg_replace("/(<\?php \/\*%%SmartyHeaderCode:{$tpl->properties['nocache_hash']}%%\*\/(.+?)\/\*\/%%SmartyHeaderCode%%\*\/\?>\n)/s", '', $compiled_code);
|
|
||||||
if ($tpl->has_nocache_code) {
|
|
||||||
// replace nocache_hash
|
|
||||||
$compiled_code = str_replace("{$tpl->properties['nocache_hash']}", $compiler->template->properties['nocache_hash'], $compiled_code);
|
|
||||||
$compiler->template->has_nocache_code = true;
|
|
||||||
}
|
|
||||||
$compiler->merged_templates[$tpl->properties['unifunc']] = $compiled_code;
|
|
||||||
$has_compiled_template = true;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
$has_compiled_template = true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// variable compile_id?
|
||||||
|
if (isset($_attr['compile_id'])) {
|
||||||
|
if (!((substr_count($_attr['compile_id'], '"') == 2 || substr_count($_attr['compile_id'], "'") == 2))
|
||||||
|
|| substr_count($_attr['compile_id'], '(') != 0 || substr_count($_attr['compile_id'], '$_smarty_tpl->') != 0
|
||||||
|
) {
|
||||||
|
$merge_compiled_includes = false;
|
||||||
|
if ($compiler->inheritance) {
|
||||||
|
$compiler->trigger_template_error(' variable compile_id not allow within {block} tags');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($compiler->template->caching && ($compiler->tag_nocache || $compiler->nocache) && $_caching != self::CACHING_NOCACHE_CODE) {
|
||||||
|
$merge_compiled_includes = false;
|
||||||
|
if ($compiler->inheritance) {
|
||||||
|
$compiler->trigger_template_error(' invalid caching mode of subtemplate within {block} tags');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($merge_compiled_includes || $compiler->inheritance) {
|
||||||
|
// we must observe different compile_id
|
||||||
|
$uid = sha1($_compile_id);
|
||||||
|
$tpl_name = null;
|
||||||
|
$nocache = false;
|
||||||
|
eval("\$tpl_name = $include_file;");
|
||||||
|
if (!isset($compiler->smarty->merged_templates_func[$tpl_name][$uid]) || $compiler->inheritance) {
|
||||||
|
$tpl = new $compiler->smarty->template_class ($tpl_name, $compiler->smarty, $compiler->template, $compiler->template->cache_id, $compiler->template->compile_id);
|
||||||
|
// save unique function name
|
||||||
|
$compiler->smarty->merged_templates_func[$tpl_name][$uid]['func'] = $tpl->properties['unifunc'] = 'content_' . str_replace('.', '_', uniqid('', true));
|
||||||
|
// use current nocache hash for inlined code
|
||||||
|
$compiler->smarty->merged_templates_func[$tpl_name][$uid]['nocache_hash'] = $tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
|
||||||
|
if ($compiler->template->caching && $_caching == self::CACHING_NOCACHE_CODE) {
|
||||||
|
// all code must be nocache
|
||||||
|
$nocache = true;
|
||||||
|
}
|
||||||
|
if ($compiler->inheritance) {
|
||||||
|
$tpl->compiler->inheritance = true;
|
||||||
|
}
|
||||||
|
// make sure whole chain gets compiled
|
||||||
|
$tpl->mustCompile = true;
|
||||||
|
if (!($tpl->source->uncompiled) && $tpl->source->exists) {
|
||||||
|
|
||||||
|
|
||||||
|
// get compiled code
|
||||||
|
$compiled_code = $tpl->compiler->compileTemplate($tpl, $nocache);
|
||||||
|
// release compiler object to free memory
|
||||||
|
unset($tpl->compiler);
|
||||||
|
// merge compiled code for {function} tags
|
||||||
|
$compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $tpl->properties['function']);
|
||||||
|
// merge filedependency
|
||||||
|
$tpl->properties['file_dependency'][$tpl->source->uid] = array($tpl->source->filepath, $tpl->source->timestamp, $tpl->source->type);
|
||||||
|
$compiler->template->properties['file_dependency'] = array_merge($compiler->template->properties['file_dependency'], $tpl->properties['file_dependency']);
|
||||||
|
// remove header code
|
||||||
|
$compiled_code = preg_replace("/(<\?php \/\*%%SmartyHeaderCode:{$tpl->properties['nocache_hash']}%%\*\/(.+?)\/\*\/%%SmartyHeaderCode%%\*\/\?>\n)/s", '', $compiled_code);
|
||||||
|
if ($tpl->has_nocache_code) {
|
||||||
|
// replace nocache_hash
|
||||||
|
$compiled_code = str_replace("{$tpl->properties['nocache_hash']}", $compiler->template->properties['nocache_hash'], $compiled_code);
|
||||||
|
$compiler->template->has_nocache_code = true;
|
||||||
|
}
|
||||||
|
$compiler->merged_templates[$tpl->properties['unifunc']] = $compiled_code;
|
||||||
|
$has_compiled_template = true;
|
||||||
|
unset ($tpl);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
$has_compiled_template = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
// delete {include} standard attributes
|
// delete {include} standard attributes
|
||||||
unset($_attr['file'], $_attr['assign'], $_attr['cache_id'], $_attr['compile_id'], $_attr['cache_lifetime'], $_attr['nocache'], $_attr['caching'], $_attr['scope'], $_attr['inline']);
|
unset($_attr['file'], $_attr['assign'], $_attr['cache_id'], $_attr['compile_id'], $_attr['cache_lifetime'], $_attr['nocache'], $_attr['caching'], $_attr['scope'], $_attr['inline']);
|
||||||
@@ -175,7 +214,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
|||||||
foreach ($_attr as $key => $value) {
|
foreach ($_attr as $key => $value) {
|
||||||
$_pairs[] = "'$key'=>$value";
|
$_pairs[] = "'$key'=>$value";
|
||||||
}
|
}
|
||||||
$_vars = 'array('.join(',',$_pairs).')';
|
$_vars = 'array(' . join(',', $_pairs) . ')';
|
||||||
$_has_vars = true;
|
$_has_vars = true;
|
||||||
} else {
|
} else {
|
||||||
$compiler->trigger_template_error('variable passing not allowed in parent/global scope', $compiler->lex->taglineno);
|
$compiler->trigger_template_error('variable passing not allowed in parent/global scope', $compiler->lex->taglineno);
|
||||||
@@ -185,19 +224,21 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
|||||||
$_has_vars = false;
|
$_has_vars = false;
|
||||||
}
|
}
|
||||||
if ($has_compiled_template) {
|
if ($has_compiled_template) {
|
||||||
$_hash = $compiler->smarty->merged_templates_func[$tpl_name]['nocache_hash'];
|
// never call inline templates in nocache mode
|
||||||
|
$compiler->suppressNocacheProcessing = true;
|
||||||
|
$_hash = $compiler->smarty->merged_templates_func[$tpl_name][$uid]['nocache_hash'];
|
||||||
$_output = "<?php /* Call merged included template \"" . $tpl_name . "\" */\n";
|
$_output = "<?php /* Call merged included template \"" . $tpl_name . "\" */\n";
|
||||||
$_output .= "\$_tpl_stack[] = \$_smarty_tpl;\n";
|
$_output .= "\$_tpl_stack[] = \$_smarty_tpl;\n";
|
||||||
$_output .= " \$_smarty_tpl = \$_smarty_tpl->setupInlineSubTemplate($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope, '$_hash');\n";
|
$_output .= " \$_smarty_tpl = \$_smarty_tpl->setupInlineSubTemplate($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope, '$_hash');\n";
|
||||||
if (isset($_assign)) {
|
if (isset($_assign)) {
|
||||||
$_output .= 'ob_start(); ';
|
$_output .= 'ob_start(); ';
|
||||||
}
|
}
|
||||||
$_output .= $compiler->smarty->merged_templates_func[$tpl_name]['func']. "(\$_smarty_tpl);\n";
|
$_output .= $compiler->smarty->merged_templates_func[$tpl_name][$uid]['func'] . "(\$_smarty_tpl);\n";
|
||||||
$_output .= "\$_smarty_tpl = array_pop(\$_tpl_stack); ";
|
$_output .= "\$_smarty_tpl = array_pop(\$_tpl_stack); ";
|
||||||
if (isset($_assign)) {
|
if (isset($_assign)) {
|
||||||
$_output .= " \$_smarty_tpl->tpl_vars[$_assign] = new Smarty_variable(ob_get_clean());";
|
$_output .= " \$_smarty_tpl->tpl_vars[$_assign] = new Smarty_variable(ob_get_clean());";
|
||||||
}
|
}
|
||||||
$_output .= "/* End of included template \"" . $tpl_name . "\" */?>";
|
$_output .= "\n/* End of included template \"" . $tpl_name . "\" */?>";
|
||||||
|
|
||||||
return $_output;
|
return $_output;
|
||||||
}
|
}
|
||||||
@@ -211,5 +252,4 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
|||||||
|
|
||||||
return $_output;
|
return $_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@@ -32,8 +32,11 @@ class Smarty_Internal_Compile_Nocache extends Smarty_Internal_CompileBase
|
|||||||
if ($_attr['nocache'] === true) {
|
if ($_attr['nocache'] === true) {
|
||||||
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
|
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
|
||||||
}
|
}
|
||||||
|
if ($compiler->template->caching) {
|
||||||
// enter nocache mode
|
// enter nocache mode
|
||||||
|
$this->openTag($compiler, 'nocache', $compiler->nocache);
|
||||||
$compiler->nocache = true;
|
$compiler->nocache = true;
|
||||||
|
}
|
||||||
// this tag does not return compiled code
|
// this tag does not return compiled code
|
||||||
$compiler->has_code = false;
|
$compiler->has_code = false;
|
||||||
|
|
||||||
@@ -62,8 +65,10 @@ class Smarty_Internal_Compile_Nocacheclose extends Smarty_Internal_CompileBase
|
|||||||
public function compile($args, $compiler)
|
public function compile($args, $compiler)
|
||||||
{
|
{
|
||||||
$_attr = $this->getAttributes($compiler, $args);
|
$_attr = $this->getAttributes($compiler, $args);
|
||||||
// leave nocache mode
|
if ($compiler->template->caching) {
|
||||||
$compiler->nocache = false;
|
// restore old nocache mode
|
||||||
|
$compiler->nocache = $this->closeTag($compiler, 'nocache');
|
||||||
|
}
|
||||||
// this tag does not return compiled code
|
// this tag does not return compiled code
|
||||||
$compiler->has_code = false;
|
$compiler->has_code = false;
|
||||||
|
|
||||||
|
@@ -24,6 +24,27 @@ class Smarty_Internal_Debug extends Smarty_Internal_Data
|
|||||||
*/
|
*/
|
||||||
public static $template_data = array();
|
public static $template_data = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of uid's which shall be ignored
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public static $ignore_uid = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ignore template
|
||||||
|
*
|
||||||
|
* @param object $template
|
||||||
|
*/
|
||||||
|
public static function ignore($template)
|
||||||
|
{
|
||||||
|
// calculate Uid if not already done
|
||||||
|
if ($template->source->uid == '') {
|
||||||
|
$template->source->filepath;
|
||||||
|
}
|
||||||
|
self::$ignore_uid[$template->source->uid] = true;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Start logging of compile time
|
* Start logging of compile time
|
||||||
*
|
*
|
||||||
@@ -31,7 +52,25 @@ class Smarty_Internal_Debug extends Smarty_Internal_Data
|
|||||||
*/
|
*/
|
||||||
public static function start_compile($template)
|
public static function start_compile($template)
|
||||||
{
|
{
|
||||||
$key = self::get_key($template);
|
static $_is_stringy = array('string' => true, 'eval' => true);
|
||||||
|
if (!empty($template->compiler->trace_uid)) {
|
||||||
|
$key = $template->compiler->trace_uid;
|
||||||
|
if (!isset(self::$template_data[$key])) {
|
||||||
|
if (isset($_is_stringy[$template->source->type])) {
|
||||||
|
self::$template_data[$key]['name'] = '\'' . substr($template->source->name, 0, 25) . '...\'';
|
||||||
|
} else {
|
||||||
|
self::$template_data[$key]['name'] = $template->source->filepath;
|
||||||
|
}
|
||||||
|
self::$template_data[$key]['compile_time'] = 0;
|
||||||
|
self::$template_data[$key]['render_time'] = 0;
|
||||||
|
self::$template_data[$key]['cache_time'] = 0;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (isset(self::$ignore_uid[$template->source->uid])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$key = self::get_key($template);
|
||||||
|
}
|
||||||
self::$template_data[$key]['start_time'] = microtime(true);
|
self::$template_data[$key]['start_time'] = microtime(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,7 +81,15 @@ class Smarty_Internal_Debug extends Smarty_Internal_Data
|
|||||||
*/
|
*/
|
||||||
public static function end_compile($template)
|
public static function end_compile($template)
|
||||||
{
|
{
|
||||||
$key = self::get_key($template);
|
if (!empty($template->compiler->trace_uid)) {
|
||||||
|
$key = $template->compiler->trace_uid;
|
||||||
|
} else {
|
||||||
|
if (isset(self::$ignore_uid[$template->source->uid])) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$key = self::get_key($template);
|
||||||
|
}
|
||||||
self::$template_data[$key]['compile_time'] += microtime(true) - self::$template_data[$key]['start_time'];
|
self::$template_data[$key]['compile_time'] += microtime(true) - self::$template_data[$key]['start_time'];
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -171,7 +218,7 @@ class Smarty_Internal_Debug extends Smarty_Internal_Data
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return (object) array('tpl_vars' => $tpl_vars, 'config_vars' => $config_vars);
|
return (object)array('tpl_vars' => $tpl_vars, 'config_vars' => $config_vars);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -192,7 +239,7 @@ class Smarty_Internal_Debug extends Smarty_Internal_Data
|
|||||||
return $key;
|
return $key;
|
||||||
} else {
|
} else {
|
||||||
if (isset($_is_stringy[$template->source->type])) {
|
if (isset($_is_stringy[$template->source->type])) {
|
||||||
self::$template_data[$key]['name'] = '\''.substr($template->source->name,0,25).'...\'';
|
self::$template_data[$key]['name'] = '\'' . substr($template->source->name, 0, 25) . '...\'';
|
||||||
} else {
|
} else {
|
||||||
self::$template_data[$key]['name'] = $template->source->filepath;
|
self::$template_data[$key]['name'] = $template->source->filepath;
|
||||||
}
|
}
|
||||||
|
@@ -1,37 +1,37 @@
|
|||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* Smarty Internal Plugin Resource Extends
|
* Smarty Internal Plugin Resource Extends
|
||||||
*
|
*
|
||||||
* @package Smarty
|
* @package Smarty
|
||||||
* @subpackage TemplateResources
|
* @subpackage TemplateResources
|
||||||
* @author Uwe Tews
|
* @author Uwe Tews
|
||||||
* @author Rodney Rehm
|
* @author Rodney Rehm
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Smarty Internal Plugin Resource Extends
|
* Smarty Internal Plugin Resource Extends
|
||||||
*
|
*
|
||||||
* Implements the file system as resource for Smarty which {extend}s a chain of template files templates
|
* Implements the file system as resource for Smarty which {extend}s a chain of template files templates
|
||||||
*
|
*
|
||||||
* @package Smarty
|
* @package Smarty
|
||||||
* @subpackage TemplateResources
|
* @subpackage TemplateResources
|
||||||
*/
|
*/
|
||||||
class Smarty_Internal_Resource_Extends extends Smarty_Resource
|
class Smarty_Internal_Resource_Extends extends Smarty_Resource
|
||||||
{
|
{
|
||||||
/**
|
/**
|
||||||
* mbstring.overload flag
|
* mbstring.overload flag
|
||||||
*
|
*
|
||||||
* @var int
|
* @var int
|
||||||
*/
|
*/
|
||||||
public $mbstring_overload = 0;
|
public $mbstring_overload = 0;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* populate Source Object with meta data from Resource
|
* populate Source Object with meta data from Resource
|
||||||
*
|
*
|
||||||
* @param Smarty_Template_Source $source source object
|
* @param Smarty_Template_Source $source source object
|
||||||
* @param Smarty_Internal_Template $_template template object
|
* @param Smarty_Internal_Template $_template template object
|
||||||
*/
|
*/
|
||||||
public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null)
|
public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null)
|
||||||
{
|
{
|
||||||
$uid = '';
|
$uid = '';
|
||||||
$sources = array();
|
$sources = array();
|
||||||
@@ -60,10 +60,10 @@ class Smarty_Internal_Resource_Extends extends Smarty_Resource
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* populate Source Object with timestamp and exists from Resource
|
* populate Source Object with timestamp and exists from Resource
|
||||||
*
|
*
|
||||||
* @param Smarty_Template_Source $source source object
|
* @param Smarty_Template_Source $source source object
|
||||||
*/
|
*/
|
||||||
public function populateTimestamp(Smarty_Template_Source $source)
|
public function populateTimestamp(Smarty_Template_Source $source)
|
||||||
{
|
{
|
||||||
$source->exists = true;
|
$source->exists = true;
|
||||||
@@ -74,84 +74,34 @@ class Smarty_Internal_Resource_Extends extends Smarty_Resource
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load template's source from files into current template object
|
* Load template's source from files into current template object
|
||||||
*
|
*
|
||||||
* @param Smarty_Template_Source $source source object
|
* @param Smarty_Template_Source $source source object
|
||||||
* @return string template source
|
* @return string template source
|
||||||
* @throws SmartyException if source cannot be loaded
|
* @throws SmartyException if source cannot be loaded
|
||||||
*/
|
*/
|
||||||
public function getContent(Smarty_Template_Source $source)
|
public function getContent(Smarty_Template_Source $source)
|
||||||
{
|
{
|
||||||
if (!$source->exists) {
|
if (!$source->exists) {
|
||||||
throw new SmartyException("Unable to read template {$source->type} '{$source->name}'");
|
throw new SmartyException("Unable to read template {$source->type} '{$source->name}'");
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->mbstring_overload = ini_get('mbstring.func_overload') & 2;
|
|
||||||
$_rdl = preg_quote($source->smarty->right_delimiter);
|
|
||||||
$_ldl = preg_quote($source->smarty->left_delimiter);
|
|
||||||
if (!$source->smarty->auto_literal) {
|
|
||||||
$al = '\s*';
|
|
||||||
} else {
|
|
||||||
$al = '';
|
|
||||||
}
|
|
||||||
$_components = array_reverse($source->components);
|
$_components = array_reverse($source->components);
|
||||||
$_first = reset($_components);
|
|
||||||
$_last = end($_components);
|
|
||||||
|
|
||||||
|
$_content = '';
|
||||||
foreach ($_components as $_component) {
|
foreach ($_components as $_component) {
|
||||||
// register dependency
|
|
||||||
if ($_component != $_first) {
|
|
||||||
$source->template->properties['file_dependency'][$_component->uid] = array($_component->filepath, $_component->timestamp, $_component->type);
|
|
||||||
}
|
|
||||||
|
|
||||||
// read content
|
// read content
|
||||||
$source->filepath = $_component->filepath;
|
$_content .= $_component->content;
|
||||||
$_content = $_component->content;
|
|
||||||
|
|
||||||
// extend sources
|
|
||||||
if ($_component != $_last) {
|
|
||||||
if (preg_match_all("!({$_ldl}{$al}block\s(.+?)\s*{$_rdl})!", $_content, $_open) !=
|
|
||||||
preg_match_all("!({$_ldl}{$al}/block\s*{$_rdl})!", $_content, $_close)) {
|
|
||||||
throw new SmartyException("unmatched {block} {/block} pairs in template {$_component->type} '{$_component->name}'");
|
|
||||||
}
|
|
||||||
preg_match_all("!{$_ldl}{$al}block\s(.+?)\s*{$_rdl}|{$_ldl}{$al}/block\s*{$_rdl}|{$_ldl}\*([\S\s]*?)\*{$_rdl}!", $_content, $_result, PREG_OFFSET_CAPTURE);
|
|
||||||
$_result_count = count($_result[0]);
|
|
||||||
$_start = 0;
|
|
||||||
while ($_start+1 < $_result_count) {
|
|
||||||
$_end = 0;
|
|
||||||
$_level = 1;
|
|
||||||
if (($this->mbstring_overload ? mb_substr($_result[0][$_start][0],0,mb_strlen($source->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start][0],0,strlen($source->smarty->left_delimiter)+1)) == $source->smarty->left_delimiter.'*') {
|
|
||||||
$_start++;
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
while ($_level != 0) {
|
|
||||||
$_end++;
|
|
||||||
if (($this->mbstring_overload ? mb_substr($_result[0][$_start + $_end][0],0,mb_strlen($source->smarty->left_delimiter,'latin1')+1, 'latin1') : substr($_result[0][$_start + $_end][0],0,strlen($source->smarty->left_delimiter)+1)) == $source->smarty->left_delimiter.'*') {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (!strpos($_result[0][$_start + $_end][0], '/')) {
|
|
||||||
$_level++;
|
|
||||||
} else {
|
|
||||||
$_level--;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$_block_content = str_replace($source->smarty->left_delimiter . '$smarty.block.parent' . $source->smarty->right_delimiter, '%%%%SMARTY_PARENT%%%%',
|
|
||||||
($this->mbstring_overload ? mb_substr($_content, $_result[0][$_start][1] + mb_strlen($_result[0][$_start][0], 'latin1'), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + mb_strlen($_result[0][$_start][0], 'latin1'), 'latin1') : substr($_content, $_result[0][$_start][1] + strlen($_result[0][$_start][0]), $_result[0][$_start + $_end][1] - $_result[0][$_start][1] - + strlen($_result[0][$_start][0]))));
|
|
||||||
Smarty_Internal_Compile_Block::saveBlockData($_block_content, $_result[0][$_start][0], $source->template, $_component->filepath);
|
|
||||||
$_start = $_start + $_end + 1;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
return $_content;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
return $_content;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Determine basename for compiled filename
|
* Determine basename for compiled filename
|
||||||
*
|
*
|
||||||
* @param Smarty_Template_Source $source source object
|
* @param Smarty_Template_Source $source source object
|
||||||
* @return string resource's basename
|
* @return string resource's basename
|
||||||
*/
|
*/
|
||||||
public function getBasename(Smarty_Template_Source $source)
|
public function getBasename(Smarty_Template_Source $source)
|
||||||
{
|
{
|
||||||
return str_replace(':', '.', basename($source->filepath));
|
return str_replace(':', '.', basename($source->filepath));
|
||||||
|
@@ -94,6 +94,10 @@ class Smarty_Internal_SmartyTemplateCompiler extends Smarty_Internal_TemplateCom
|
|||||||
// init the lexer/parser to compile the template
|
// init the lexer/parser to compile the template
|
||||||
$this->lex = new $this->lexer_class($_content, $this);
|
$this->lex = new $this->lexer_class($_content, $this);
|
||||||
$this->parser = new $this->parser_class($this->lex, $this);
|
$this->parser = new $this->parser_class($this->lex, $this);
|
||||||
|
if ($this->inheritance_child) {
|
||||||
|
// start state on child templates
|
||||||
|
$this->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBODY);
|
||||||
|
}
|
||||||
if ($this->smarty->_parserdebug)
|
if ($this->smarty->_parserdebug)
|
||||||
$this->parser->PrintTrace();
|
$this->parser->PrintTrace();
|
||||||
// get tokens from lexer and parse them
|
// get tokens from lexer and parse them
|
||||||
|
@@ -167,16 +167,14 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
if (!$this->source->recompiled) {
|
if (!$this->source->recompiled) {
|
||||||
$this->properties['file_dependency'] = array();
|
$this->properties['file_dependency'] = array();
|
||||||
if ($this->source->components) {
|
if ($this->source->components) {
|
||||||
|
// for the extends resource the compiler will fill it
|
||||||
// uses real resource for file dependency
|
// uses real resource for file dependency
|
||||||
$source = end($this->source->components);
|
// $source = end($this->source->components);
|
||||||
$this->properties['file_dependency'][$this->source->uid] = array($this->source->filepath, $this->source->timestamp, $source->type);
|
// $this->properties['file_dependency'][$this->source->uid] = array($this->source->filepath, $this->source->timestamp, $source->type);
|
||||||
} else {
|
} else {
|
||||||
$this->properties['file_dependency'][$this->source->uid] = array($this->source->filepath, $this->source->timestamp, $this->source->type);
|
$this->properties['file_dependency'][$this->source->uid] = array($this->source->filepath, $this->source->timestamp, $this->source->type);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if ($this->smarty->debugging) {
|
|
||||||
Smarty_Internal_Debug::start_compile($this);
|
|
||||||
}
|
|
||||||
// compile locking
|
// compile locking
|
||||||
if ($this->smarty->compile_locking && !$this->source->recompiled) {
|
if ($this->smarty->compile_locking && !$this->source->recompiled) {
|
||||||
if ($saved_timestamp = $this->compiled->timestamp) {
|
if ($saved_timestamp = $this->compiled->timestamp) {
|
||||||
@@ -203,9 +201,6 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
$this->compiled->exists = true;
|
$this->compiled->exists = true;
|
||||||
$this->compiled->isCompiled = true;
|
$this->compiled->isCompiled = true;
|
||||||
}
|
}
|
||||||
if ($this->smarty->debugging) {
|
|
||||||
Smarty_Internal_Debug::end_compile($this);
|
|
||||||
}
|
|
||||||
// release compiler object to free memory
|
// release compiler object to free memory
|
||||||
unset($this->compiler);
|
unset($this->compiler);
|
||||||
}
|
}
|
||||||
@@ -413,7 +408,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
$output .= $plugins_string;
|
$output .= $plugins_string;
|
||||||
$output .= $content;
|
$output .= $content;
|
||||||
if (!$this->source->recompiled) {
|
if (!$this->source->recompiled) {
|
||||||
$output .= '<?php }} ?>';
|
$output .= "<?php }} ?>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
return $output;
|
return $output;
|
||||||
|
@@ -132,13 +132,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
|
|||||||
if (!$_template->source->uncompiled) {
|
if (!$_template->source->uncompiled) {
|
||||||
$_smarty_tpl = $_template;
|
$_smarty_tpl = $_template;
|
||||||
if ($_template->source->recompiled) {
|
if ($_template->source->recompiled) {
|
||||||
if ($this->smarty->debugging) {
|
|
||||||
Smarty_Internal_Debug::start_compile($_template);
|
|
||||||
}
|
|
||||||
$code = $_template->compiler->compileTemplate($_template);
|
$code = $_template->compiler->compileTemplate($_template);
|
||||||
if ($this->smarty->debugging) {
|
|
||||||
Smarty_Internal_Debug::end_compile($_template);
|
|
||||||
}
|
|
||||||
if ($this->smarty->debugging) {
|
if ($this->smarty->debugging) {
|
||||||
Smarty_Internal_Debug::start_render($_template);
|
Smarty_Internal_Debug::start_render($_template);
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user