mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-05 19:04: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);
|
||||||
}
|
}
|
||||||
|
@@ -68,12 +68,60 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
public $merged_templates = array();
|
public $merged_templates = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* flag when compiling {block}
|
* sources which must be compiled
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $sources = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* flag that we are inside {block}
|
||||||
*
|
*
|
||||||
* @var bool
|
* @var bool
|
||||||
*/
|
*/
|
||||||
public $inheritance = false;
|
public $inheritance = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* flag when compiling inheritance child template
|
||||||
|
*
|
||||||
|
* @var bool
|
||||||
|
*/
|
||||||
|
public $inheritance_child = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* uid of templates called by {extends} for recursion check
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $extends_uid = array();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* source line offset for error messages
|
||||||
|
*
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
public $trace_line_offset = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* trace uid
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $trace_uid = '';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* trace file path
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
public $trace_filepath = '';
|
||||||
|
/**
|
||||||
|
* stack for tracing file and line of nested {block} tags
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
public $trace_stack = array();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* plugins loaded by default plugin handler
|
* plugins loaded by default plugin handler
|
||||||
*
|
*
|
||||||
@@ -162,9 +210,10 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
* Method to compile a Smarty template
|
* Method to compile a Smarty template
|
||||||
*
|
*
|
||||||
* @param Smarty_Internal_Template $template template object to compile
|
* @param Smarty_Internal_Template $template template object to compile
|
||||||
* @return bool true if compiling succeeded, false if it failed
|
* @param bool $nocache true is shall be compiled in nocache mode
|
||||||
|
* @return bool true if compiling succeeded, false if it failed
|
||||||
*/
|
*/
|
||||||
public function compileTemplate(Smarty_Internal_Template $template)
|
public function compileTemplate(Smarty_Internal_Template $template, $nocache = false)
|
||||||
{
|
{
|
||||||
if (empty($template->properties['nocache_hash'])) {
|
if (empty($template->properties['nocache_hash'])) {
|
||||||
$template->properties['nocache_hash'] = $this->nocache_hash;
|
$template->properties['nocache_hash'] = $this->nocache_hash;
|
||||||
@@ -172,13 +221,13 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
$this->nocache_hash = $template->properties['nocache_hash'];
|
$this->nocache_hash = $template->properties['nocache_hash'];
|
||||||
}
|
}
|
||||||
// flag for nochache sections
|
// flag for nochache sections
|
||||||
$this->nocache = false;
|
$this->nocache = $nocache;
|
||||||
$this->tag_nocache = false;
|
$this->tag_nocache = false;
|
||||||
// save template object in compiler class
|
// save template object in compiler class
|
||||||
$this->template = $template;
|
$this->template = $template;
|
||||||
// reset has noche code flag
|
// reset has nocache code flag
|
||||||
$this->template->has_nocache_code = false;
|
$this->template->has_nocache_code = false;
|
||||||
$this->smarty->_current_file = $saved_filepath = $this->template->source->filepath;
|
$save_source = $this->template->source;
|
||||||
// template header code
|
// template header code
|
||||||
$template_header = '';
|
$template_header = '';
|
||||||
if (!$this->suppressHeader) {
|
if (!$this->suppressHeader) {
|
||||||
@@ -186,29 +235,52 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
$template_header .= " compiled from \"" . $this->template->source->filepath . "\" */ ?>\n";
|
$template_header .= " compiled from \"" . $this->template->source->filepath . "\" */ ?>\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
do {
|
if (empty($this->template->source->components)) {
|
||||||
// flag for aborting current and start recompile
|
$this->sources = array($template->source);
|
||||||
$this->abort_and_recompile = false;
|
} else {
|
||||||
// get template source
|
// we have array of inheritance templates by extends: resource
|
||||||
$_content = $template->source->content;
|
$this->sources = array_reverse($template->source->components);
|
||||||
// run prefilter if required
|
}
|
||||||
if ((isset($this->smarty->autoload_filters['pre']) || isset($this->smarty->registered_filters['pre'])) && !$this->suppressFilter) {
|
$loop = 0;
|
||||||
$_content = Smarty_Internal_Filter_Handler::runFilter('pre', $_content, $template);
|
// the $this->sources array can get additional elements while compiling by the {extends} tag
|
||||||
|
while ($this->template->source = array_shift($this->sources)) {
|
||||||
|
$this->smarty->_current_file = $this->template->source->filepath;
|
||||||
|
if ($this->smarty->debugging) {
|
||||||
|
Smarty_Internal_Debug::start_compile($this->template);
|
||||||
}
|
}
|
||||||
// on empty template just return header
|
$no_sources = count($this->sources);
|
||||||
if ($_content == '') {
|
if ($loop || $no_sources) {
|
||||||
if ($this->suppressTemplatePropertyHeader) {
|
$this->template->properties['file_dependency'][$this->template->source->uid] = array($this->template->source->filepath, $this->template->source->timestamp, $this->template->source->type);
|
||||||
$code = '';
|
}
|
||||||
} else {
|
$loop++;
|
||||||
$code = $template_header . $template->createTemplateCodeFrame();
|
if ($no_sources) {
|
||||||
|
$this->inheritance_child = true;
|
||||||
|
} else {
|
||||||
|
$this->inheritance_child = false;
|
||||||
|
}
|
||||||
|
do {
|
||||||
|
$_compiled_code = '';
|
||||||
|
// flag for aborting current and start recompile
|
||||||
|
$this->abort_and_recompile = false;
|
||||||
|
// get template source
|
||||||
|
$_content = $this->template->source->content;
|
||||||
|
if ($_content != '') {
|
||||||
|
// run prefilter if required
|
||||||
|
if ((isset($this->smarty->autoload_filters['pre']) || isset($this->smarty->registered_filters['pre'])) && !$this->suppressFilter) {
|
||||||
|
$_content = Smarty_Internal_Filter_Handler::runFilter('pre', $_content, $template);
|
||||||
|
}
|
||||||
|
// call compiler
|
||||||
|
$_compiled_code = $this->doCompile($_content);
|
||||||
}
|
}
|
||||||
|
} while ($this->abort_and_recompile);
|
||||||
return $code;
|
if ($this->smarty->debugging) {
|
||||||
|
Smarty_Internal_Debug::end_compile($this->template);
|
||||||
}
|
}
|
||||||
// call compiler
|
}
|
||||||
$_compiled_code = $this->doCompile($_content);
|
// restore source
|
||||||
} while ($this->abort_and_recompile);
|
$this->template->source = $save_source;
|
||||||
$this->template->source->filepath = $saved_filepath;
|
unset($save_source);
|
||||||
|
$this->smarty->_current_file = $this->template->source->filepath;
|
||||||
// free memory
|
// free memory
|
||||||
unset($this->parser->root_buffer, $this->parser->current_buffer, $this->parser, $this->lex, $this->template);
|
unset($this->parser->root_buffer, $this->parser->current_buffer, $this->parser, $this->lex, $this->template);
|
||||||
self::$_tag_objects = array();
|
self::$_tag_objects = array();
|
||||||
@@ -220,7 +292,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// run postfilter if required on compiled template code
|
// run postfilter if required on compiled template code
|
||||||
if ((isset($this->smarty->autoload_filters['post']) || isset($this->smarty->registered_filters['post'])) && !$this->suppressFilter) {
|
if ((isset($this->smarty->autoload_filters['post']) || isset($this->smarty->registered_filters['post'])) && !$this->suppressFilter && $_compiled_code != '') {
|
||||||
$_compiled_code = Smarty_Internal_Filter_Handler::runFilter('post', $_compiled_code, $template);
|
$_compiled_code = Smarty_Internal_Filter_Handler::runFilter('post', $_compiled_code, $template);
|
||||||
}
|
}
|
||||||
if ($this->suppressTemplatePropertyHeader) {
|
if ($this->suppressTemplatePropertyHeader) {
|
||||||
@@ -241,8 +313,8 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
* It executes the required compile plugin for the Smarty tag
|
* It executes the required compile plugin for the Smarty tag
|
||||||
*
|
*
|
||||||
* @param string $tag tag name
|
* @param string $tag tag name
|
||||||
* @param array $args array with tag attributes
|
* @param array $args array with tag attributes
|
||||||
* @param array $parameter array with compilation parameter
|
* @param array $parameter array with compilation parameter
|
||||||
* @return string compiled code
|
* @return string compiled code
|
||||||
*/
|
*/
|
||||||
public function compileTag($tag, $args, $parameter = array())
|
public function compileTag($tag, $args, $parameter = array())
|
||||||
@@ -257,7 +329,8 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
}
|
}
|
||||||
// check nocache option flag
|
// check nocache option flag
|
||||||
if (in_array("'nocache'", $args) || in_array(array('nocache' => 'true'), $args)
|
if (in_array("'nocache'", $args) || in_array(array('nocache' => 'true'), $args)
|
||||||
|| in_array(array('nocache' => '"true"'), $args) || in_array(array('nocache' => "'true'"), $args)) {
|
|| in_array(array('nocache' => '"true"'), $args) || in_array(array('nocache' => "'true'"), $args)
|
||||||
|
) {
|
||||||
$this->tag_nocache = true;
|
$this->tag_nocache = true;
|
||||||
}
|
}
|
||||||
// compile the smarty tag (required compile classes to compile the tag are autoloaded)
|
// compile the smarty tag (required compile classes to compile the tag are autoloaded)
|
||||||
@@ -281,7 +354,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
// tag did not produce compiled code
|
// tag did not produce compiled code
|
||||||
return '';
|
return null;
|
||||||
} else {
|
} else {
|
||||||
// map_named attributes
|
// map_named attributes
|
||||||
if (isset($args['_attr'])) {
|
if (isset($args['_attr'])) {
|
||||||
@@ -297,7 +370,8 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
if (isset($this->smarty->registered_objects[$tag]) && isset($parameter['object_methode'])) {
|
if (isset($this->smarty->registered_objects[$tag]) && isset($parameter['object_methode'])) {
|
||||||
$methode = $parameter['object_methode'];
|
$methode = $parameter['object_methode'];
|
||||||
if (!in_array($methode, $this->smarty->registered_objects[$tag][3]) &&
|
if (!in_array($methode, $this->smarty->registered_objects[$tag][3]) &&
|
||||||
(empty($this->smarty->registered_objects[$tag][1]) || in_array($methode, $this->smarty->registered_objects[$tag][1]))) {
|
(empty($this->smarty->registered_objects[$tag][1]) || in_array($methode, $this->smarty->registered_objects[$tag][1]))
|
||||||
|
) {
|
||||||
return $this->callTagCompiler('private_object_function', $args, $parameter, $tag, $methode);
|
return $this->callTagCompiler('private_object_function', $args, $parameter, $tag, $methode);
|
||||||
} elseif (in_array($methode, $this->smarty->registered_objects[$tag][3])) {
|
} elseif (in_array($methode, $this->smarty->registered_objects[$tag][3])) {
|
||||||
return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $methode);
|
return $this->callTagCompiler('private_object_block_function', $args, $parameter, $tag, $methode);
|
||||||
@@ -468,10 +542,10 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
* plugin filename format: Smarty_Internal_Tagname.php
|
* plugin filename format: Smarty_Internal_Tagname.php
|
||||||
*
|
*
|
||||||
* @param string $tag tag name
|
* @param string $tag tag name
|
||||||
* @param array $args list of tag attributes
|
* @param array $args list of tag attributes
|
||||||
* @param mixed $param1 optional parameter
|
* @param mixed $param1 optional parameter
|
||||||
* @param mixed $param2 optional parameter
|
* @param mixed $param2 optional parameter
|
||||||
* @param mixed $param3 optional parameter
|
* @param mixed $param3 optional parameter
|
||||||
* @return string compiled code
|
* @return string compiled code
|
||||||
*/
|
*/
|
||||||
public function callTagCompiler($tag, $args, $param1 = null, $param2 = null, $param3 = null)
|
public function callTagCompiler($tag, $args, $param1 = null, $param2 = null, $param3 = null)
|
||||||
@@ -557,8 +631,8 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
/**
|
/**
|
||||||
* Check for plugins by default plugin handler
|
* Check for plugins by default plugin handler
|
||||||
*
|
*
|
||||||
* @param string $tag name of tag
|
* @param string $tag name of tag
|
||||||
* @param string $plugin_type type of plugin
|
* @param string $plugin_type type of plugin
|
||||||
* @return boolean true if found
|
* @return boolean true if found
|
||||||
*/
|
*/
|
||||||
public function getPluginFromDefaultHandler($tag, $plugin_type)
|
public function getPluginFromDefaultHandler($tag, $plugin_type)
|
||||||
@@ -567,7 +641,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
$script = null;
|
$script = null;
|
||||||
$cacheable = true;
|
$cacheable = true;
|
||||||
$result = call_user_func_array(
|
$result = call_user_func_array(
|
||||||
$this->smarty->default_plugin_handler_func, array($tag, $plugin_type, $this->template, &$callback, &$script, &$cacheable)
|
$this->smarty->default_plugin_handler_func, array($tag, $plugin_type, $this->template, &$callback, &$script, &$cacheable)
|
||||||
);
|
);
|
||||||
if ($result) {
|
if ($result) {
|
||||||
$this->tag_nocache = $this->tag_nocache || !$cacheable;
|
$this->tag_nocache = $this->tag_nocache || !$cacheable;
|
||||||
@@ -607,7 +681,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
* If the content is compiled code and it should be not cached the code is injected
|
* If the content is compiled code and it should be not cached the code is injected
|
||||||
* into the rendered output.
|
* into the rendered output.
|
||||||
*
|
*
|
||||||
* @param string $content content of template element
|
* @param string $content content of template element
|
||||||
* @param boolean $is_code true if content is compiled code
|
* @param boolean $is_code true if content is compiled code
|
||||||
* @return string content
|
* @return string content
|
||||||
*/
|
*/
|
||||||
@@ -617,9 +691,10 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
if ($is_code && !empty($content)) {
|
if ($is_code && !empty($content)) {
|
||||||
// generate replacement code
|
// generate replacement code
|
||||||
if ((!($this->template->source->recompiled) || $this->forceNocache) && $this->template->caching && !$this->suppressNocacheProcessing &&
|
if ((!($this->template->source->recompiled) || $this->forceNocache) && $this->template->caching && !$this->suppressNocacheProcessing &&
|
||||||
($this->nocache || $this->tag_nocache || $this->forceNocache == 2)) {
|
($this->nocache || $this->tag_nocache)
|
||||||
|
) {
|
||||||
$this->template->has_nocache_code = true;
|
$this->template->has_nocache_code = true;
|
||||||
$_output = addcslashes($content,'\'\\');
|
$_output = addcslashes($content, '\'\\');
|
||||||
$_output = str_replace("^#^", "'", $_output);
|
$_output = str_replace("^#^", "'", $_output);
|
||||||
$_output = "<?php echo '/*%%SmartyNocache:{$this->nocache_hash}%%*/" . $_output . "/*/%%SmartyNocache:{$this->nocache_hash}%%*/';?>\n";
|
$_output = "<?php echo '/*%%SmartyNocache:{$this->nocache_hash}%%*/" . $_output . "/*/%%SmartyNocache:{$this->nocache_hash}%%*/';?>\n";
|
||||||
// make sure we include modifier plugins for nocache code
|
// make sure we include modifier plugins for nocache code
|
||||||
@@ -641,6 +716,47 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
return $_output;
|
return $_output;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* push current file and line offset on stack for tracing {block} source lines
|
||||||
|
*
|
||||||
|
* @param string $file new filename
|
||||||
|
* @param string $uid uid of file
|
||||||
|
* @param string $debug false debug end_compile shall not be called
|
||||||
|
* @param int $line line offset to source
|
||||||
|
*/
|
||||||
|
public function pushTrace($file, $uid, $line, $debug = true)
|
||||||
|
{
|
||||||
|
if ($this->smarty->debugging && $debug) {
|
||||||
|
Smarty_Internal_Debug::end_compile($this->template);
|
||||||
|
}
|
||||||
|
array_push($this->trace_stack, array($this->smarty->_current_file, $this->trace_filepath, $this->trace_uid, $this->trace_line_offset));
|
||||||
|
$this->trace_filepath = $this->smarty->_current_file = $file;
|
||||||
|
$this->trace_uid = $uid;
|
||||||
|
$this->trace_line_offset = $line ;
|
||||||
|
if ($this->smarty->debugging) {
|
||||||
|
Smarty_Internal_Debug::start_compile($this->template);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* restore file and line offset
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function popTrace()
|
||||||
|
{
|
||||||
|
if ($this->smarty->debugging) {
|
||||||
|
Smarty_Internal_Debug::end_compile($this->template);
|
||||||
|
}
|
||||||
|
$r = array_pop($this->trace_stack);
|
||||||
|
$this->smarty->_current_file = $r[0];
|
||||||
|
$this->trace_filepath = $r[1];
|
||||||
|
$this->trace_uid = $r[2];
|
||||||
|
$this->trace_line_offset = $r[3];
|
||||||
|
if ($this->smarty->debugging) {
|
||||||
|
Smarty_Internal_Debug::start_compile($this->template);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* display compiler error messages without dying
|
* display compiler error messages without dying
|
||||||
*
|
*
|
||||||
@@ -649,8 +765,8 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
*
|
*
|
||||||
* If parameter $args contains a string this is used as error message
|
* If parameter $args contains a string this is used as error message
|
||||||
*
|
*
|
||||||
* @param string $args individual error message or null
|
* @param string $args individual error message or null
|
||||||
* @param string $line line-number
|
* @param string $line line-number
|
||||||
* @throws SmartyCompilerException when an unexpected token is found
|
* @throws SmartyCompilerException when an unexpected token is found
|
||||||
*/
|
*/
|
||||||
public function trigger_template_error($args = null, $line = null)
|
public function trigger_template_error($args = null, $line = null)
|
||||||
@@ -659,8 +775,9 @@ abstract class Smarty_Internal_TemplateCompilerBase
|
|||||||
if (!isset($line)) {
|
if (!isset($line)) {
|
||||||
$line = $this->lex->line;
|
$line = $this->lex->line;
|
||||||
}
|
}
|
||||||
|
// $line += $this->trace_line_offset;
|
||||||
$match = preg_split("/\n/", $this->lex->data);
|
$match = preg_split("/\n/", $this->lex->data);
|
||||||
$error_text = 'Syntax Error in template "' . $this->template->source->filepath . '" on line ' . $line . ' "' . trim(preg_replace('![\t\r\n]+!', ' ', $match[$line - 1])) . '" ';
|
$error_text = 'Syntax error in template "' . (empty($this->trace_filepath) ? $this->template->source->filepath : $this->trace_filepath) . '" on line ' . ($line + $this->trace_line_offset) . ' "' . trim(preg_replace('![\t\r\n]+!', ' ', $match[$line - 1])) . '" ';
|
||||||
if (isset($args)) {
|
if (isset($args)) {
|
||||||
// individual error message
|
// individual error message
|
||||||
$error_text .= $args;
|
$error_text .= $args;
|
||||||
|
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