Merge pull request #7 from uwetews/master

-bugfix and enhancement on subtemplate {include} and template {function}
This commit is contained in:
uwetews
2014-11-01 22:52:01 +01:00
14 changed files with 456 additions and 308 deletions

View File

@@ -1,4 +1,10 @@
===== 3.1.22-dev ===== (xx.xx.2014)
01.11.2014
-bugfix and enhancement on subtemplate {include} and template {function} tags.
* Calling a template which has a nocache section could fail if it was called from a cached and a not cached subtemplate.
* Calling the same subtemplate cached and not cached with the $smarty->merge_compiled_includes enabled could cause problems
* Many smaller related changes
30.10.2014
- bugfix access to class constant by object like {$object::CONST} or variable class name {$class::CONST} did not work (forum 25301)

View File

@@ -2,7 +2,7 @@
/**
* Project: Smarty: the PHP compiling template engine
* File: Smarty.class.php
*
* SVN: $Id: Smarty.class.php 4897 2014-10-14 22:29:58Z Uwe.Tews@googlemail.com $
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
@@ -24,7 +24,7 @@
* @author Uwe Tews
* @author Rodney Rehm
* @package Smarty
* @version 3.1.22-dev
* @version 3.1-DEV
*/
/**
@@ -110,8 +110,7 @@ class Smarty extends Smarty_Internal_TemplateBase
/**
* smarty version
*/
const SMARTY_VERSION = 'Smarty-3.1.22-dev/1';
const SMARTY_VERSION = 'Smarty-3.1.21-dev/2';
/**
* define variable scopes
@@ -493,12 +492,6 @@ class Smarty extends Smarty_Internal_TemplateBase
/**#@-*/
/**
* global template functions
*
* @var array
*/
public $template_functions = array();
/**
* resource type used if none given
* Must be an valid key of $registered_resources.
@@ -657,12 +650,6 @@ class Smarty extends Smarty_Internal_TemplateBase
* @var bool
*/
public $_parserdebug = false;
/**
* Saved parameter of merged templates during compilation
*
* @var array
*/
public $merged_templates_func = array();
/**
* Cache of is_file results of loadPlugin()

View File

@@ -386,11 +386,7 @@ class Smarty_Template_Cached
if ($smarty->debugging) {
Smarty_Internal_Debug::start_cache($_template);
}
if ($handler->process($_template, $this) === false) {
$this->valid = false;
} else {
$this->processed = true;
}
$this->process($_template);
if ($smarty->debugging) {
Smarty_Internal_Debug::end_cache($_template);
}
@@ -413,6 +409,20 @@ class Smarty_Template_Cached
}
}
/**
* Process cached template
*
* @param Smarty_Internal_Template $_template template object
*/
public function process(Smarty_Internal_Template $_template)
{
if ($this->handler->process($_template, $this) === false) {
$this->valid = false;
} else {
$this->processed = true;
}
}
/**
* Write this cache object to handler
*

View File

@@ -173,20 +173,18 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
$_tpl->compiler->suppressHeader = true;
$_tpl->compiler->suppressFilter = true;
$_tpl->compiler->suppressTemplatePropertyHeader = true;
$_tpl->compiler->suppressMergedTemplates = true;
$nocache = $compiler->nocache || $compiler->tag_nocache;
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));
$_output = str_replace(self::parent, $compiler->parser->current_buffer->to_smarty_php(), $_tpl->compiler->compileTemplate($_tpl, $nocache, $compiler->parent_compiler));
} elseif ($compiler->template->block_data[$_name]['mode'] == 'prepend') {
$_output = $_tpl->compiler->compileTemplate($_tpl, $nocache) . $compiler->parser->current_buffer->to_smarty_php();
$_output = $_tpl->compiler->compileTemplate($_tpl, $nocache, $compiler->parent_compiler) . $compiler->parser->current_buffer->to_smarty_php();
} elseif ($compiler->template->block_data[$_name]['mode'] == 'append') {
$_output = $compiler->parser->current_buffer->to_smarty_php() . $_tpl->compiler->compileTemplate($_tpl, $nocache);
$_output = $compiler->parser->current_buffer->to_smarty_php() . $_tpl->compiler->compileTemplate($_tpl, $nocache, $compiler->parent_compiler);
} elseif (!empty($compiler->template->block_data[$_name])) {
$_output = $_tpl->compiler->compileTemplate($_tpl, $nocache);
$_output = $_tpl->compiler->compileTemplate($_tpl, $nocache, $compiler->parent_compiler);
}
$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->merged_templates = array_merge($compiler->merged_templates, $_tpl->compiler->merged_templates);
$compiler->template->properties['tpl_function'] = array_merge($compiler->template->properties['tpl_function'], $_tpl->properties['tpl_function']);
$compiler->template->variable_filters = $_tpl->variable_filters;
if ($_tpl->has_nocache_code) {
$compiler->template->has_nocache_code = true;
@@ -245,7 +243,6 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase
*
* @param $compiler
* @param string $source source text
*
*/
static function blockSource($compiler, $source)
{

View File

@@ -55,13 +55,11 @@ class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase
// output will be stored in a smarty variable instead of being displayed
$_assign = $_attr['assign'];
}
$_name = $_attr['name'];
if ($compiler->compiles_template_function) {
$compiler->called_functions[] = trim($_name, "'\"");
}
$_name = trim($_attr['name'], "'\"");
unset($_attr['name'], $_attr['assign'], $_attr['nocache']);
// set flag (compiled code of {function} must be included in cache file
if ($compiler->nocache || $compiler->tag_nocache) {
if (!$compiler->template->caching || $compiler->nocache || $compiler->tag_nocache) {
$compiler->parent_compiler->templateProperties['tpl_function']['to_cache'][$_name] = true;
$_nocache = 'true';
} else {
$_nocache = 'false';
@@ -74,54 +72,14 @@ class Smarty_Internal_Compile_Call extends Smarty_Internal_CompileBase
$_paramsArray[] = "'$_key'=>$_value";
}
}
if (isset($compiler->template->properties['function'][$_name]['parameter'])) {
foreach ($compiler->template->properties['function'][$_name]['parameter'] as $_key => $_value) {
if (!isset($_attr[$_key])) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} else {
$_paramsArray[] = "'$_key'=>$_value";
}
}
}
} elseif (isset($compiler->smarty->template_functions[$_name]['parameter'])) {
foreach ($compiler->smarty->template_functions[$_name]['parameter'] as $_key => $_value) {
if (!isset($_attr[$_key])) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} else {
$_paramsArray[] = "'$_key'=>$_value";
}
}
}
}
//variable name?
if (!(strpos($_name, '$') === false)) {
$call_cache = $_name;
$call_function = '$tmp = "smarty_template_function_".' . $_name . '; $tmp';
} else {
$_name = trim($_name, "'\"");
$call_cache = "'{$_name}'";
$call_function = 'smarty_template_function_' . $_name;
}
$_params = 'array(' . implode(",", $_paramsArray) . ')';
$_hash = str_replace('-', '_', $compiler->template->properties['nocache_hash']);
//$compiler->suppressNocacheProcessing = true;
// was there an assign attribute
if (isset($_assign)) {
if ($compiler->template->caching) {
$_output = "<?php ob_start(); Smarty_Internal_Function_Call_Handler::call ({$call_cache},\$_smarty_tpl,{$_params},'{$_hash}',{$_nocache}); \$_smarty_tpl->assign({$_assign}, ob_get_clean());?>\n";
$_output = "<?php ob_start();\$_smarty_tpl->callTemplateFunction ('{$_name}', \$_smarty_tpl, {$_params}, {$_nocache}); \$_smarty_tpl->assign({$_assign}, ob_get_clean());?>\n";
} else {
$_output = "<?php ob_start(); {$call_function}(\$_smarty_tpl,{$_params}); \$_smarty_tpl->assign({$_assign}, ob_get_clean());?>\n";
$_output = "<?php \$_smarty_tpl->callTemplateFunction ('{$_name}', \$_smarty_tpl, {$_params}, {$_nocache});?>\n";
}
} else {
if ($compiler->template->caching) {
$_output = "<?php Smarty_Internal_Function_Call_Handler::call ({$call_cache},\$_smarty_tpl,{$_params},'{$_hash}',{$_nocache});?>\n";
} else {
$_output = "<?php {$call_function}(\$_smarty_tpl,{$_params});?>\n";
}
}
return $_output;
}
}

View File

@@ -56,39 +56,18 @@ class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase
$compiler->trigger_template_error('nocache option not allowed', $compiler->lex->taglineno);
}
unset($_attr['nocache']);
$save = array($_attr, $compiler->parser->current_buffer,
$compiler->template->has_nocache_code, $compiler->template->required_plugins);
$this->openTag($compiler, 'function', $save);
$_name = trim($_attr['name'], "'\"");
unset($_attr['name']);
$save = array($_attr, $compiler->parser->current_buffer,
$compiler->template->has_nocache_code, $compiler->template->required_plugins, $compiler->template->caching);
$this->openTag($compiler, 'function', $save);
// set flag that we are compiling a template function
$compiler->compiles_template_function = true;
$compiler->template->properties['function'][$_name]['parameter'] = array();
/** @var Smarty_Internal_Template $_smarty_tpl
* used in evaluated code
*/
$_smarty_tpl = $compiler->template;
foreach ($_attr as $_key => $_data) {
eval ('$tmp=' . $_data . ';');
$compiler->template->properties['function'][$_name]['parameter'][$_key] = $tmp;
}
$compiler->smarty->template_functions[$_name]['parameter'] = $compiler->template->properties['function'][$_name]['parameter'];
if ($compiler->template->caching) {
$output = '';
} else {
$output = "<?php if (!function_exists('smarty_template_function_{$_name}')) {
function smarty_template_function_{$_name}(\$_smarty_tpl,\$params) {
\$saved_tpl_vars = \$_smarty_tpl->tpl_vars;
foreach (\$_smarty_tpl->smarty->template_functions['{$_name}']['parameter'] as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);};
foreach (\$params as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);}?>";
}
// Init temporary context
$compiler->template->required_plugins = array('compiled' => array(), 'nocache' => array());
$compiler->parser->current_buffer = new _smarty_template_buffer($compiler->parser);
$compiler->parser->current_buffer->append_subtree(new _smarty_tag($compiler->parser, $output));
$compiler->template->has_nocache_code = false;
$compiler->has_code = false;
$compiler->template->properties['function'][$_name]['compiled'] = '';
$compiler->template->caching = true;
return true;
}
}
@@ -101,6 +80,13 @@ class Smarty_Internal_Compile_Function extends Smarty_Internal_CompileBase
*/
class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
{
/**
* Compiler object
*
* @var object
*/
private $compiler = null;
/**
* Compiles code for the {/function} tag
*
@@ -112,51 +98,120 @@ class Smarty_Internal_Compile_Functionclose extends Smarty_Internal_CompileBase
*/
public function compile($args, $compiler, $parameter)
{
$_attr = $this->getAttributes($compiler, $args);
$this->compiler = $compiler;
$saved_data = $this->closeTag($compiler, array('function'));
$_name = trim($saved_data[0]['name'], "'\"");
// build plugin include code
$plugins_string = '';
if (!empty($compiler->template->required_plugins['compiled'])) {
$plugins_string = '<?php ';
foreach ($compiler->template->required_plugins['compiled'] as $tmp) {
foreach ($tmp as $data) {
$plugins_string .= "if (!is_callable('{$data['function']}')) include '{$data['file']}';\n";
}
}
$plugins_string .= '?>';
}
if (!empty($compiler->template->required_plugins['nocache'])) {
$plugins_string .= "<?php echo '/*%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/<?php ";
foreach ($compiler->template->required_plugins['nocache'] as $tmp) {
foreach ($tmp as $data) {
$plugins_string .= "if (!is_callable(\'{$data['function']}\')) include \'{$data['file']}\';\n";
}
}
$plugins_string .= "?>/*/%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/';?>\n";
}
// if caching save template function for possible nocache call
if ($compiler->template->caching) {
$compiler->template->properties['function'][$_name]['compiled'] .= $plugins_string
. $compiler->parser->current_buffer->to_smarty_php();
$compiler->template->properties['function'][$_name]['nocache_hash'] = $compiler->template->properties['nocache_hash'];
$compiler->template->properties['function'][$_name]['has_nocache_code'] = $compiler->template->has_nocache_code;
$compiler->template->properties['function'][$_name]['called_functions'] = $compiler->called_functions;
$compiler->called_functions = array();
$compiler->smarty->template_functions[$_name] = $compiler->template->properties['function'][$_name];
$compiler->has_code = false;
$output = true;
} else {
$output = $plugins_string . $compiler->parser->current_buffer->to_smarty_php() . "<?php \$_smarty_tpl->tpl_vars = \$saved_tpl_vars;
foreach (Smarty::\$global_tpl_vars as \$key => \$value) if(!isset(\$_smarty_tpl->tpl_vars[\$key])) \$_smarty_tpl->tpl_vars[\$key] = \$value;}}?>\n";
}
$_attr = $saved_data[0];
$_name = trim($_attr['name'], "'\"");
// reset flag that we are compiling a template function
$compiler->compiles_template_function = false;
// restore old compiler status
$compiler->parser->current_buffer = $saved_data[1];
$compiler->template->has_nocache_code = $compiler->template->has_nocache_code | $saved_data[2];
$compiler->template->required_plugins = $saved_data[3];
$compiler->parent_compiler->templateProperties['tpl_function']['param'][$_name]['called_functions'] = $compiler->called_functions;
$compiler->parent_compiler->templateProperties['tpl_function']['param'][$_name]['compiled_filepath'] = $compiler->parent_compiler->template->compiled->filepath;
$compiler->called_functions = array();
$_parameter = $_attr;
unset($_parameter['name']);
// default parameter
$_paramsArray = array();
foreach ($_parameter as $_key => $_value) {
if (is_int($_key)) {
$_paramsArray[] = "$_key=>$_value";
} else {
$_paramsArray[] = "'$_key'=>$_value";
}
}
if (!empty($_paramsArray)) {
$_params = 'array(' . implode(",", $_paramsArray) . ')';
$_paramsCode = "\$params = array_merge(($_params), \$params);\n";
} else {
$_paramsCode = '';
}
$_functionCode = $compiler->parser->current_buffer->to_smarty_php();
// setup buffer for template function code
$compiler->parser->current_buffer = new _smarty_template_buffer($compiler->parser);
return $output;
$_funcName = "smarty_template_function_{$_name}_{$compiler->template->properties['nocache_hash']}";
$_funcNameCaching = $_funcName . '_nocache';
if ($compiler->template->has_nocache_code) {
$compiler->parent_compiler->templateProperties['tpl_function']['param'][$_name]['call_name_caching'] = $_funcNameCaching;
$output = "<?php\n";
$output .= "/* {$_funcNameCaching} */\n";
$output .= "if (!function_exists('{$_funcNameCaching}')) {\n";
$output .= "function {$_funcNameCaching} (\$_smarty_tpl,\$params) {\n";
// build plugin include code
if (!empty($compiler->template->required_plugins['compiled'])) {
foreach ($compiler->template->required_plugins['compiled'] as $tmp) {
foreach ($tmp as $data) {
$output .= "if (!is_callable('{$data['function']}')) include '{$data['file']}';\n";
}
}
}
if (!empty($compiler->template->required_plugins['nocache'])) {
$output .= "echo '/*%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/<?php ";
foreach ($compiler->template->required_plugins['nocache'] as $tmp) {
foreach ($tmp as $data) {
$output .= "if (!is_callable(\'{$data['function']}\')) include \'{$data['file']}\';\n";
}
}
$output .= "?>/*/%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%*/';\n";
}
$output .= "\$saved_tpl_vars = \$_smarty_tpl->tpl_vars;\n";
$output .= $_paramsCode;
$output .= "foreach (\$params as \$key => \$value) {\n\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);\n}\n";
$output .= "ob_start();\n?>";
$compiler->parser->current_buffer->append_subtree(new _smarty_tag($compiler->parser, $output));
$compiler->parser->current_buffer->append_subtree(new _smarty_tag($compiler->parser, $_functionCode));
$output = "<?php echo str_replace('{$compiler->template->properties['nocache_hash']}', \"{\$_smarty_tpl->properties['nocache_hash']}\", ob_get_clean());\n";
$output .= "\$_smarty_tpl->tpl_vars = \$saved_tpl_vars;
foreach (Smarty::\$global_tpl_vars as \$key => \$value) if(!isset(\$_smarty_tpl->tpl_vars[\$key])) \$_smarty_tpl->tpl_vars[\$key] = \$value;\n}\n}\n";
$output .= "/*/ {$_funcName}_nocache */\n";
$output .= "?>\n";
$compiler->parser->current_buffer->append_subtree(new _smarty_tag($compiler->parser, $output));
$_functionCode = preg_replace_callback("/((<\?php )?echo '\/\*%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%\*\/([\S\s]*?)\/\*\/%%SmartyNocache:{$compiler->template->properties['nocache_hash']}%%\*\/';(\?>\n)?)/", array($this, 'removeNocache'), $_functionCode);
}
$compiler->parent_compiler->templateProperties['tpl_function']['param'][$_name]['call_name'] = $_funcName;
$output = "<?php\n";
$output .= "/* {$_funcName} */\n";
$output .= "if (!function_exists('{$_funcName}')) {\n";
$output .= "function {$_funcName}(\$_smarty_tpl,\$params) {\n";
// build plugin include code
if (!empty($compiler->template->required_plugins['nocache'])) {
$compiler->template->required_plugins['compiled'] = array_merge($compiler->template->required_plugins['compiled'], $compiler->template->required_plugins['nocache']);
}
if (!empty($compiler->template->required_plugins['compiled'])) {
foreach ($compiler->template->required_plugins['compiled'] as $tmp) {
foreach ($tmp as $data) {
$output .= "if (!is_callable('{$data['function']}')) include '{$data['file']}';\n";
}
}
}
$output .= "\$saved_tpl_vars = \$_smarty_tpl->tpl_vars;\n";
$output .= $_paramsCode;
$output .= "foreach (\$params as \$key => \$value) {\n\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);\n}?>";
$compiler->parser->current_buffer->append_subtree(new _smarty_tag($compiler->parser, $output));
$compiler->parser->current_buffer->append_subtree(new _smarty_tag($compiler->parser, $_functionCode));
$output = "<?php \$_smarty_tpl->tpl_vars = \$saved_tpl_vars;
foreach (Smarty::\$global_tpl_vars as \$key => \$value) if(!isset(\$_smarty_tpl->tpl_vars[\$key])) \$_smarty_tpl->tpl_vars[\$key] = \$value;\n}\n}\n";
$output .= "/*/ {$_funcName} */\n";
$output .= "?>\n";
$compiler->parser->current_buffer->append_subtree(new _smarty_tag($compiler->parser, $output));
$compiler->parent_compiler->templateFunctionCode .= $compiler->parser->current_buffer->to_smarty_php();
// restore old buffer
$compiler->parser->current_buffer = $saved_data[1];
// restore old status
$compiler->template->has_nocache_code = $saved_data[2];
$compiler->template->required_plugins = $saved_data[3];
$compiler->template->caching = $saved_data[4];
return true;
}
/**
* @param $match
*
* @return mixed
*/
function removeNocache($match)
{
$code = preg_replace("/((<\?php )?echo '\/\*%%SmartyNocache:{$this->compiler->template->properties['nocache_hash']}%%\*\/)|(\/\*\/%%SmartyNocache:{$this->compiler->template->properties['nocache_hash']}%%\*\/';(\?>\n)?)/", '', $match[0]);
$code = str_replace(array('\\\'', '\\\\\''), array('\'', '\\\''), $code);
return $code;
}
}

View File

@@ -154,8 +154,6 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
$compiler->trigger_template_error(' invalid caching mode of subtemplate within {block} tags');
}
}
}
if ($merge_compiled_includes) {
// we must observe different compile_id and caching
$uid = sha1($_compile_id . ($_caching ? '--caching' : '--nocaching'));
$tpl_name = null;
@@ -164,12 +162,10 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
*/
$_smarty_tpl = $compiler->template;
eval("\$tpl_name = $include_file;");
if (!isset($compiler->smarty->merged_templates_func[$tpl_name][$uid])) {
if (!isset($compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$uid])) {
$tpl = new $compiler->smarty->template_class ($tpl_name, $compiler->smarty, $compiler->template, $compiler->template->cache_id, $compiler->template->compile_id, $_caching);
// save unique function name
$compiler->smarty->merged_templates_func[$tpl_name][$uid]['func'] = $tpl->properties['unifunc'] = 'content_' . str_replace(array('.', ','), '_', 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'];
$compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$uid]['func'] = $tpl->properties['unifunc'] = 'content_' . str_replace(array('.', ','), '_', uniqid('', true));
if ($compiler->inheritance) {
$tpl->compiler->inheritance = true;
}
@@ -178,11 +174,11 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
if (!($tpl->source->uncompiled) && $tpl->source->exists) {
// get compiled code
$compiled_code = $tpl->compiler->compileTemplate($tpl);
// release compiler object to free memory
$compiled_code = $tpl->compiler->compileTemplate($tpl, null, $compiler->parent_compiler);
$compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$uid]['nocache_hash'] = $tpl->properties['nocache_hash'];
unset($tpl->compiler);
// merge compiled code for {function} tags
$compiler->template->properties['function'] = array_merge($compiler->template->properties['function'], $tpl->properties['function']);
$compiler->template->properties['tpl_function'] = array_merge($compiler->template->properties['tpl_function'], $tpl->properties['tpl_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']);
@@ -193,7 +189,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
$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;
$compiler->parent_compiler->mergedSubTemplatesCode[$tpl->properties['unifunc']] = $compiled_code;
$has_compiled_template = true;
unset ($tpl);
}
@@ -222,24 +218,21 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
if ($has_compiled_template) {
// never call inline templates in nocache mode
$compiler->suppressNocacheProcessing = true;
$_hash = $compiler->smarty->merged_templates_func[$tpl_name][$uid]['nocache_hash'];
$_hash = $compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$uid]['nocache_hash'];
$_output = "<?php /* Call merged included template \"" . $tpl_name . "\" */\n";
$_output .= "\$_tpl_stack[] = \$_smarty_tpl;\n";
// $_output .= "\$_tpl_stack[] = \$_smarty_tpl_save = \$_smarty_tpl;\n";
if (!empty($nccode) && $_caching == 9999 && $_smarty_tpl->caching) {
$compiler->suppressNocacheProcessing = false;
$_output .= substr($compiler->processNocacheCode('<?php ' . $nccode . "?>\n", true), 6, - 3);
$compiler->suppressNocacheProcessing = true;
}
$_output .= " \$_smarty_tpl = \$_smarty_tpl->setupInlineSubTemplate($include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope, '$_hash');\n";
if (isset($_assign)) {
$_output .= 'ob_start(); ';
$_output .= " \$_smarty_tpl->tpl_vars[$_assign] = new Smarty_variable(\$_smarty_tpl->getInlineSubTemplate({$include_file}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_parent_scope}, '{$_hash}', '{$compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$uid]['func']}'));\n";
} else {
$_output .= "echo \$_smarty_tpl->getInlineSubTemplate({$include_file}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_parent_scope}, '{$_hash}', '{$compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$uid]['func']}');\n";
}
$_output .= $compiler->smarty->merged_templates_func[$tpl_name][$uid]['func'] . "(\$_smarty_tpl);\n";
$_output .= "\$_smarty_tpl = array_pop(\$_tpl_stack); ";
if (isset($_assign)) {
$_output .= " \$_smarty_tpl->tpl_vars[$_assign] = new Smarty_variable(ob_get_clean());";
}
$_output .= "\n/* End of included template \"" . $tpl_name . "\" */?>";
// $_output .= "\$_smarty_tpl = array_pop(\$_tpl_stack); ";
$_output .= "/* End of included template \"" . $tpl_name . "\" */?>\n";
return $_output;
}

View File

@@ -20,33 +20,35 @@ class Smarty_Internal_Function_Call_Handler
* It does create a PHP function at the first call
*
* @param string $_name template function name
* @param Smarty_Internal_Template $_template template object
* @param Smarty_Internal_Template $_smarty_tpl
* @param $_function
* @param array $_params Smarty variables passed as call parameter
* @param string $_hash nocache hash value
* @param bool $_nocache nocache flag
*
* @return bool
*/
public static function call($_name, Smarty_Internal_Template $_template, $_params, $_hash, $_nocache)
public static function call($_name, Smarty_Internal_Template $_smarty_tpl, $_function, $_params, $_nocache)
{
if ($_nocache) {
$_function = "smarty_template_function_{$_name}_nocache";
} else {
$_function = "smarty_template_function_{$_hash}_{$_name}";
$funcParam = $_smarty_tpl->properties['tpl_function']['param'][$_name];
$code = file_get_contents($funcParam['compiled_filepath']);
if (preg_match("/\/\* {$_function} \*\/([\S\s]*?)\/\*\/ {$_function} \*\//", $code, $match)) {
$output = "\n";
$output .= $match[0];
$output .= "?>\n";
}
if (!is_callable($_function)) {
$_code = "function {$_function}(\$_smarty_tpl,\$params) {
\$saved_tpl_vars = \$_smarty_tpl->tpl_vars;
foreach (\$_smarty_tpl->smarty->template_functions['{$_name}']['parameter'] as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);};
foreach (\$params as \$key => \$value) {\$_smarty_tpl->tpl_vars[\$key] = new Smarty_variable(\$value);}?>";
if ($_nocache) {
$_code .= preg_replace(array("!<\?php echo \\'/\*%%SmartyNocache:{$_template->smarty->template_functions[$_name]['nocache_hash']}%%\*/|/\*/%%SmartyNocache:{$_template->smarty->template_functions[$_name]['nocache_hash']}%%\*/\\';\?>!",
"!\\\'!"), array('', "'"), $_template->smarty->template_functions[$_name]['compiled']);
$_template->smarty->template_functions[$_name]['called_nocache'] = true;
} else {
$_code .= preg_replace("/{$_template->smarty->template_functions[$_name]['nocache_hash']}/", $_template->properties['nocache_hash'], $_template->smarty->template_functions[$_name]['compiled']);
unset($code, $match);
eval($output);
if (function_exists($_function)) {
$_function ($_smarty_tpl, $_params);
$tplPtr = $_smarty_tpl;
while (isset($tplPtr->parent) && !isset($tplPtr->parent->cached)) {
$tplPtr = $tplPtr->parent;
}
$_code .= "<?php \$_smarty_tpl->tpl_vars = \$saved_tpl_vars;}";
eval($_code);
if (isset($tplPtr->parent->cached)) {
$cached = $tplPtr->parent->cached;
}
$_function($_template, $_params);
return true;
}
return false;
}
}

View File

@@ -309,7 +309,7 @@ class _smarty_template_buffer extends _smarty_parsetree
}
$newCode = $this->subtrees[$key]->to_smarty_php();
if ((preg_match('/^\s*<\?php\s+/', $newCode) && preg_match('/\s*\?>\s*$/', $subtree))) {
$subtree = preg_replace('/\s*\?>\s*$/', "\n", $subtree);
$subtree = preg_replace('/\s*\?>\s*$/', "", $subtree);
$subtree .= preg_replace('/^\s*<\?php\s+/', '', $newCode);
} else {
$subtree .= $newCode;
@@ -325,7 +325,6 @@ class _smarty_template_buffer extends _smarty_parsetree
}
return $code;
}
}
/**

View File

@@ -86,7 +86,7 @@ class Smarty_Internal_SmartyTemplateCompiler extends Smarty_Internal_TemplateCom
*
* @return bool true if compiling succeeded, false if it failed
*/
protected function doCompile($_content)
protected function doCompile($_content, $isTemplateSource = false)
{
/* here is where the compiling takes place. Smarty
tags in the templates are replaces with PHP code,
@@ -94,6 +94,9 @@ class Smarty_Internal_SmartyTemplateCompiler extends Smarty_Internal_TemplateCom
// init the lexer/parser to compile the template
$this->lex = new $this->lexer_class($_content, $this);
$this->parser = new $this->parser_class($this->lex, $this);
if ($isTemplateSource) {
$this->parser->insertPhpCode("<?php\n\$_smarty_tpl->properties['nocache_hash'] = '{$this->nocache_hash}';\n?>\n");
}
if ($this->inheritance_child) {
// start state on child templates
$this->lex->yypushstate(Smarty_Internal_Templatelexer::CHILDBODY);

View File

@@ -67,7 +67,9 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
*/
public $properties = array('file_dependency' => array(),
'nocache_hash' => '',
'function' => array());
'tpl_function' => array(),
'type' => 'compiled',
);
/**
* required plugins
*
@@ -238,11 +240,12 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
/** @var Smarty_Internal_Template $_smarty_tpl
* used in evaluated code
*/
$_smarty_tpl = $this;
eval("?>" . $content);
$this->cached->valid = true;
$this->cached->processed = true;
/**
* $_smarty_tpl = $this;
* eval("?>" . $content);
* $this->cached->valid = true;
* $this->cached->processed = true;
*/
return $this->cached->write($this, $content);
}
@@ -275,6 +278,9 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
// clone cached template object because of possible recursive call
$tpl = clone $this->smarty->template_objects[$_templateId];
$tpl->parent = $this;
if ((bool) $tpl->caching !== (bool) $caching) {
unset($tpl->compiled);
}
$tpl->caching = $caching;
$tpl->cache_lifetime = $cache_lifetime;
} else {
@@ -316,12 +322,13 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
* @param int $parent_scope scope in which {include} should execute
* @param string $hash nocache hash code
*
* @returns string template content
* @returns object template object
*/
public function setupInlineSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $hash)
{
$tpl = new $this->smarty->template_class($template, $this->smarty, $this, $cache_id, $compile_id, $caching, $cache_lifetime);
$tpl->properties['nocache_hash'] = $hash;
$tpl->properties['tpl_function'] = $this->properties['tpl_function'];
// get variables from calling scope
if ($parent_scope == Smarty::SCOPE_LOCAL) {
$tpl->tpl_vars = $this->tpl_vars;
@@ -346,6 +353,62 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
return $tpl;
}
/**
* Template code runtime function to set up an inline subtemplate
*
* @param string $template the resource handle of the template file
* @param mixed $cache_id cache id to be used with this template
* @param mixed $compile_id compile id to be used with this template
* @param integer $caching cache mode
* @param integer $cache_lifetime life time of cache data
* @param $data
* @param int $parent_scope scope in which {include} should execute
* @param string $hash nocache hash code
* @param string $content_func name of content function
*
* @returns object template content
*/
public function getInlineSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $hash, $content_func)
{
$tpl = $this->setupInlineSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $hash);
ob_start();
$content_func($tpl);
return str_replace($tpl->properties['nocache_hash'], $this->properties['nocache_hash'], ob_get_clean());
}
/**
* Call template function
*
* @param string $name template function name
* @param object $_smarty_tpl template object
* @param array $params parameter array
* @param bool $nocache true if called nocache
*/
public function callTemplateFunction($name, $_smarty_tpl, $params, $nocache)
{
if (isset($_smarty_tpl->properties['tpl_function']['param'][$name])) {
if (!$_smarty_tpl->caching || ($_smarty_tpl->caching && $nocache) || $_smarty_tpl->properties['type'] !== 'cache') {
$_smarty_tpl->properties['tpl_function']['to_cache'][$name] = true;
$function = $_smarty_tpl->properties['tpl_function']['param'][$name]['call_name'];
} else {
if (isset($_smarty_tpl->properties['tpl_function']['param'][$name]['call_name_caching'])) {
$function = $_smarty_tpl->properties['tpl_function']['param'][$name]['call_name_caching'];
} else {
$function = $_smarty_tpl->properties['tpl_function']['param'][$name]['call_name'];
}
}
if (function_exists($function)) {
$function ($_smarty_tpl, $params);
return;
}
// try to load template function dynamically
if (Smarty_Internal_Function_Call_Handler::call($name, $_smarty_tpl, $function, $params, $nocache)) {
return;
}
}
throw new SmartyException("Unable to find template function '{$name}'");
}
/**
* Create code frame for compiled and cached templates
*
@@ -391,32 +454,17 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
}
// build property code
$this->properties['has_nocache_code'] = $this->has_nocache_code;
$output = '';
$output = '<?php ';
if (!$this->source->recompiled) {
$output = "<?php /*%%SmartyHeaderCode:{$this->properties['nocache_hash']}%%*/";
$output .= "/*%%SmartyHeaderCode:{$this->properties['nocache_hash']}%%*/";
if ($this->smarty->direct_access_security) {
$output .= "if(!defined('SMARTY_DIR')) exit('no direct access allowed');\n";
}
}
if ($cache) {
// remove compiled code of{function} definition
unset($this->properties['function']);
if (!empty($this->smarty->template_functions)) {
// copy code of {function} tags called in nocache mode
foreach ($this->smarty->template_functions as $name => $function_data) {
if (isset($function_data['called_nocache'])) {
foreach ($function_data['called_functions'] as $func_name) {
$this->smarty->template_functions[$func_name]['called_nocache'] = true;
}
}
}
foreach ($this->smarty->template_functions as $name => $function_data) {
if (isset($function_data['called_nocache'])) {
unset($function_data['called_nocache'], $function_data['called_functions'], $this->smarty->template_functions[$name]['called_nocache']);
$this->properties['function'][$name] = $function_data;
}
}
}
$this->properties['type'] = 'cache';
} else {
$this->properties['type'] = 'compiled';
}
$this->properties['version'] = Smarty::SMARTY_VERSION;
if (!isset($this->properties['unifunc'])) {
@@ -424,14 +472,34 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
}
if (!$this->source->recompiled) {
$output .= "\$_valid = \$_smarty_tpl->decodeProperties(" . var_export($this->properties, true) . ',' . ($cache ? 'true' : 'false') . "); /*/%%SmartyHeaderCode%%*/?>\n";
$output .= '<?php if ($_valid && !is_callable(\'' . $this->properties['unifunc'] . '\')) {function ' . $this->properties['unifunc'] . '($_smarty_tpl) {?>';
$output .= "<?php if (\$_valid && !is_callable('{$this->properties['unifunc']}')) {function {$this->properties['unifunc']} (\$_smarty_tpl) {\n";
}
$output .= $plugins_string;
$output .= $content;
$output .= "\$_saved_type = \$_smarty_tpl->properties['type'];\n";
$output .= "\$_smarty_tpl->properties['type'] = \$_smarty_tpl->caching ? 'cache' : 'compiled';?>\n";
$output .= $plugins_string . $content;
$output .= "<?php \$_smarty_tpl->properties['type'] = \$_saved_type;?>\n";
if (!$this->source->recompiled) {
$output .= "<?php }} ?>\n";
}
if ($cache && isset($this->properties['tpl_function']['param'])) {
$requiredFunctions = array();
foreach ($this->properties['tpl_function']['param'] as $name => $param) {
if (isset($this->properties['tpl_function']['to_cache'][$name])) {
$requiredFunctions[$param['compiled_filepath']][$name] = $param;
}
}
foreach ($requiredFunctions as $filepath => $functions) {
$code = file_get_contents($filepath);
foreach ($functions as $name => $param) {
if (preg_match("/\/\* {$param['call_name']} \*\/([\S\s]*?)\/\*\/ {$param['call_name']} \*\//", $code, $match)) {
$output .= "<?php \n";
$output .= $match[0];
$output .= "?>\n";
}
}
unset($code, $match);
}
}
return $output;
}
@@ -447,26 +515,14 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
*/
public function decodeProperties($properties, $cache = false)
{
$this->has_nocache_code = $properties['has_nocache_code'];
$this->properties['nocache_hash'] = $properties['nocache_hash'];
if (isset($properties['cache_lifetime'])) {
$this->properties['cache_lifetime'] = $properties['cache_lifetime'];
}
if (isset($properties['file_dependency'])) {
$this->properties['file_dependency'] = array_merge($this->properties['file_dependency'], $properties['file_dependency']);
}
if (!empty($properties['function'])) {
$this->properties['function'] = array_merge($this->properties['function'], $properties['function']);
$this->smarty->template_functions = array_merge($this->smarty->template_functions, $properties['function']);
}
$this->properties['version'] = (isset($properties['version'])) ? $properties['version'] : '';
$this->properties['unifunc'] = $properties['unifunc'];
// check file dependencies at compiled code
$properties['version'] = (isset($properties['version'])) ? $properties['version'] : '';
$is_valid = true;
if ($this->properties['version'] != Smarty::SMARTY_VERSION) {
if (Smarty::SMARTY_VERSION != $properties['version']) {
// new version must rebuild
$is_valid = false;
} elseif (((!$cache && $this->smarty->compile_check && empty($this->compiled->_properties) && !$this->compiled->isCompiled) || $cache && ($this->smarty->compile_check === true || $this->smarty->compile_check === Smarty::COMPILECHECK_ON)) && !empty($this->properties['file_dependency'])) {
foreach ($this->properties['file_dependency'] as $_file_to_check) {
} elseif (((!$cache && $this->smarty->compile_check && empty($this->compiled->_properties) && !$this->compiled->isCompiled) || $cache && ($this->smarty->compile_check === true || $this->smarty->compile_check === Smarty::COMPILECHECK_ON)) && !empty($properties['file_dependency'])) {
// check file dependencies at compiled code
foreach ($properties['file_dependency'] as $_file_to_check) {
if ($_file_to_check[2] == 'file' || $_file_to_check[2] == 'php') {
if ($this->source->filepath == $_file_to_check[0] && isset($this->source->timestamp)) {
// do not recheck current template
@@ -490,8 +546,8 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
if ($cache) {
// CACHING_LIFETIME_SAVED cache expiry has to be validated here since otherwise we'd define the unifunc
if ($this->caching === Smarty::CACHING_LIFETIME_SAVED &&
$this->properties['cache_lifetime'] >= 0 &&
(time() > ($this->cached->timestamp + $this->properties['cache_lifetime']))
$properties['cache_lifetime'] >= 0 &&
(time() > ($this->cached->timestamp + $properties['cache_lifetime']))
) {
$is_valid = false;
}
@@ -503,7 +559,23 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
if (!$cache) {
$this->compiled->_properties = $properties;
}
if ($is_valid) {
$this->has_nocache_code = $properties['has_nocache_code'];
// $this->properties['nocache_hash'] = $properties['nocache_hash'];
if (isset($properties['cache_lifetime'])) {
$this->properties['cache_lifetime'] = $properties['cache_lifetime'];
}
if (isset($properties['file_dependency'])) {
$this->properties['file_dependency'] = array_merge($this->properties['file_dependency'], $properties['file_dependency']);
}
$this->properties['tpl_function']['param'] = isset($this->parent->properties['tpl_function']['param']) ? $this->parent->properties['tpl_function']['param'] : array();
if (isset($properties['tpl_function']['param'])) {
$this->properties['tpl_function']['param'] = array_merge($this->properties['tpl_function']['param'], $properties['tpl_function']['param']);
}
$this->properties['version'] = $properties['version'];
$this->properties['unifunc'] = $properties['unifunc'];
$this->properties['type'] = $properties['type'];
}
return $is_valid;
}

View File

@@ -112,8 +112,6 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
}
}
}
// must reset merge template date
$_template->smarty->merged_templates_func = array();
// get rendered template
// disable caching for evaluated code
if ($_template->source->recompiled) {
@@ -220,6 +218,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
}
if ($_template->parent instanceof Smarty_Internal_Template) {
$_template->parent->properties['file_dependency'] = array_merge($_template->parent->properties['file_dependency'], $_template->properties['file_dependency']);
$_template->parent->properties['tpl_function'] = array_merge($_template->parent->properties['tpl_function'], $_template->properties['tpl_function']);
foreach ($_template->required_plugins as $code => $tmp1) {
foreach ($tmp1 as $name => $tmp) {
foreach ($tmp as $type => $data) {
@@ -249,7 +248,8 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
if (isset($cache_parts[0][$curr_idx])) {
$_template->properties['has_nocache_code'] = true;
// remove nocache tags from cache output
$output .= preg_replace("!/\*/?%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*/!", '', $cache_parts[0][$curr_idx]);
//$output .= preg_replace("!/\*/?%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*/!", '', $cache_parts[0][$curr_idx]);
$output .= $cache_parts[1][$curr_idx];
}
}
if (!$no_output_filter && !$_template->has_nocache_code && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) {
@@ -259,18 +259,45 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
/** @var Smarty_Internal_Template $_smarty_tpl
* used in evaluated code
*/
$_smarty_tpl = $_template;
// $_template->properties['type'] = 'cache';
/// $_template->properties['cache_lifetime'] = $this->cache_lifetime;
// $_template->properties['unifunc'] = 'content_' . str_replace(array('.', ','), '_', uniqid('', true));
// $content = $_template->createTemplateCodeFrame($output, true);
try {
ob_start();
eval("?>" . $output);
ob_get_clean();
}
catch (Exception $e) {
ob_get_clean();
throw $e;
}
// write cache file content
$_template->writeCachedContent($output);
unset($output);
$_template->cached->handler->process($_template);
try {
ob_start();
array_unshift($_template->_capture_stack, array());
//
// render cached template
//
$_template->properties['unifunc']($_template);
// any unclosed {capture} tags ?
if (isset($_template->_capture_stack[0][0])) {
$_template->capture_error();
}
array_shift($_template->_capture_stack);
$_output = ob_get_clean();
}
catch (Exception $e) {
ob_get_clean();
throw $e;
}
// write cache file content
$_template->writeCachedContent($output);
if ($this->smarty->debugging) {
Smarty_Internal_Debug::end_cache($_template);
}

View File

@@ -22,7 +22,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
*
* @var mixed
*/
private $nocache_hash = null;
public $nocache_hash = null;
/**
* suppress generation of nocache code
@@ -31,13 +31,6 @@ abstract class Smarty_Internal_TemplateCompilerBase
*/
public $suppressNocacheProcessing = false;
/**
* suppress generation of merged template code
*
* @var bool
*/
public $suppressMergedTemplates = false;
/**
* compile tag objects
*
@@ -60,11 +53,25 @@ abstract class Smarty_Internal_TemplateCompilerBase
public $template = null;
/**
* merged templates
* merged included sub template data
*
* @var array
*/
public $merged_templates = array();
public $mergedSubTemplatesData = array();
/**
* merged sub template code
*
* @var array
*/
public $mergedSubTemplatesCode = array();
/**
* collected template properties during compilation
*
* @var array
*/
public $templateProperties = array();
/**
* sources which must be compiled
@@ -178,12 +185,18 @@ abstract class Smarty_Internal_TemplateCompilerBase
public $compiles_template_function = false;
/**
* called subfuntions from template function
* called sub functions from template function
*
* @var array
*/
public $called_functions = array();
/**
* compiled template function code
*
* @var string
*/
public $templateFunctionCode = '';
/**
* flags for used modifier plugins
*
@@ -198,6 +211,13 @@ abstract class Smarty_Internal_TemplateCompilerBase
*/
public $known_modifier_type = array();
/**
* parent compiler object for merged subtemplates and template functions
*
* @var Smarty_Internal_TemplateCompilerBase
*/
public $parent_compiler = null;
/**
* method to compile a Smarty template
*
@@ -212,7 +232,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
*/
public function __construct()
{
$this->nocache_hash = str_replace(array('.', ','), '-', uniqid(rand(), true));
$this->nocache_hash = str_replace(array('.', ','), '_', uniqid(rand(), true));
}
/**
@@ -223,13 +243,16 @@ abstract class Smarty_Internal_TemplateCompilerBase
*
* @return bool true if compiling succeeded, false if it failed
*/
public function compileTemplate(Smarty_Internal_Template $template, $nocache = false)
public function compileTemplate(Smarty_Internal_Template $template, $nocache = null, $parent_compiler = null)
{
$this->parent_compiler = $parent_compiler ? $parent_compiler : $this;
$nocache = isset($nocache) ? $nocache : false;
if (empty($template->properties['nocache_hash'])) {
$template->properties['nocache_hash'] = $this->nocache_hash;
} else {
$this->nocache_hash = $template->properties['nocache_hash'];
}
$template->properties['type'] = $template->caching ? 'cache' : 'compiled';
// flag for nochache sections
$this->nocache = $nocache;
$this->tag_nocache = false;
@@ -280,7 +303,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
$_content = Smarty_Internal_Filter_Handler::runFilter('pre', $_content, $template);
}
// call compiler
$_compiled_code = $this->doCompile($_content);
$_compiled_code = $this->doCompile($_content, true);
}
} while ($this->abort_and_recompile);
if ($this->smarty->debugging) {
@@ -292,12 +315,12 @@ abstract class Smarty_Internal_TemplateCompilerBase
unset($save_source);
$this->smarty->_current_file = $this->template->source->filepath;
// 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);
self::$_tag_objects = array();
// return compiled code to template object
$merged_code = '';
if (!$this->suppressMergedTemplates && !empty($this->merged_templates)) {
foreach ($this->merged_templates as $code) {
if (!empty($this->mergedSubTemplatesCode)) {
foreach ($this->mergedSubTemplatesCode as $code) {
$merged_code .= $code;
}
}
@@ -305,15 +328,27 @@ abstract class Smarty_Internal_TemplateCompilerBase
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);
}
if (!empty($this->templateProperties)) {
$this->template->properties['tpl_function'] = $this->templateProperties['tpl_function'];
}
if ($this->suppressTemplatePropertyHeader) {
$code = $_compiled_code . $merged_code;
$_compiled_code .= $merged_code;
} else {
$code = $template_header . $template->createTemplateCodeFrame($_compiled_code) . $merged_code;
$_compiled_code = $template_header . $template->createTemplateCodeFrame($_compiled_code) . $merged_code;
}
if (!empty($this->templateFunctionCode)) {
// run postfilter if required on compiled template code
if ((isset($this->smarty->autoload_filters['post']) || isset($this->smarty->registered_filters['post'])) && !$this->suppressFilter) {
$_compiled_code .= Smarty_Internal_Filter_Handler::runFilter('post', $this->templateFunctionCode, $template);
} else {
$_compiled_code .= $this->templateFunctionCode;
}
}
// unset content because template inheritance could have replace source with parent code
unset ($template->source->content);
return $code;
$this->parent_compiler = null;
$this->template = null;
return $_compiled_code;
}
/**
@@ -347,7 +382,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
}
// compile the smarty tag (required compile classes to compile the tag are autoloaded)
if (($_output = $this->callTagCompiler($tag, $args, $parameter)) === false) {
if (isset($this->smarty->template_functions[$tag])) {
if (isset($this->parent_compiler->templateProperties['tpl_function']['param'][$tag])) {
// template defined by {template} tag
$args['_attr']['name'] = "'" . $tag . "'";
$_output = $this->callTagCompiler('call', $args, $parameter);

View File

@@ -762,7 +762,11 @@ class Smarty_Template_Source
public function getCompiled($_template)
{
// check runtime cache
$_cache_key = $this->unique_resource . '#' . $_template->compile_id;
$_cache_key = $this->unique_resource . '#';
if ($_template->caching) {
$_cache_key .= 'caching#';
}
$_cache_key .= $_template->compile_id;
if (isset(Smarty_Resource::$compileds[$_cache_key])) {
return Smarty_Resource::$compileds[$_cache_key];
}