mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-04 18:34:27 +02:00
- optimize internal subtemplate handling
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
===== 3.1.28-dev===== (xx.xx.2015)
|
||||
14.09.2015
|
||||
- optimize autoloader
|
||||
- optimize subtemplate handling
|
||||
|
||||
30.08.2015
|
||||
- size optimization move some runtime functions into extension
|
||||
|
@@ -119,7 +119,7 @@ class Smarty extends Smarty_Internal_TemplateBase
|
||||
/**
|
||||
* smarty version
|
||||
*/
|
||||
const SMARTY_VERSION = '3.1.28-dev/55';
|
||||
const SMARTY_VERSION = '3.1.28-dev/56';
|
||||
|
||||
/**
|
||||
* define variable scopes
|
||||
|
@@ -71,15 +71,35 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
||||
// check and get attributes
|
||||
$_attr = $this->getAttributes($compiler, $args);
|
||||
|
||||
// save possible attributes
|
||||
$include_file = $_attr['file'];
|
||||
if ($compiler->has_variable_string ||
|
||||
!((substr_count($include_file, '"') == 2 || substr_count($include_file, "'") == 2)) ||
|
||||
substr_count($include_file, '(') != 0 || substr_count($include_file, '$_smarty_tpl->') != 0
|
||||
) {
|
||||
$variable_template = true;
|
||||
$hashResourceName = $fullResourceName = $source_resource = $_attr['file'];
|
||||
$variable_template = false;
|
||||
$cache_tpl = false;
|
||||
// parse resource_name
|
||||
if (preg_match('/^([\'"])(([A-Za-z0-9_\-]{2,})[:])?(([^$()]+)|(.+))\1$/', $source_resource, $match)) {
|
||||
$type = !empty($match[3]) ? $match[3] : $compiler->template->smarty->default_resource_type;
|
||||
$name = !empty($match[5]) ? $match[5] : $match[6];
|
||||
$handler = Smarty_Resource::load($compiler->smarty, $type);
|
||||
if ($handler->recompiled || $handler->uncompiled) {
|
||||
$variable_template = true;
|
||||
}
|
||||
if (!$variable_template) {
|
||||
if ($type != 'string') {
|
||||
$fullResourceName = "{$type}:{$name}";
|
||||
$compiled = $compiler->parent_compiler->template->compiled;
|
||||
if (isset($compiled->includes[$fullResourceName])) {
|
||||
$compiled->includes[$fullResourceName] ++;
|
||||
$cache_tpl = true;
|
||||
} else {
|
||||
$compiled->includes[$fullResourceName] = 1;
|
||||
}
|
||||
$fullResourceName = "'{$fullResourceName}'";
|
||||
}
|
||||
}
|
||||
if (empty($match[5])) {
|
||||
$variable_template = true;
|
||||
}
|
||||
} else {
|
||||
$variable_template = false;
|
||||
$variable_template = true;
|
||||
}
|
||||
|
||||
if (isset($_attr['assign'])) {
|
||||
@@ -100,7 +120,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
||||
}
|
||||
|
||||
//
|
||||
if ($variable_template || $compiler->loopNesting > 0) {
|
||||
if ($cache_tpl || $variable_template || $compiler->loopNesting > 0) {
|
||||
$_cache_tpl = 'true';
|
||||
} else {
|
||||
$_cache_tpl = 'false';
|
||||
@@ -191,28 +211,26 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
||||
$t_hash = sha1($c_id . ($_caching ? '--caching' : '--nocaching'));
|
||||
$tpl_name = null;
|
||||
|
||||
/** @var Smarty_Internal_Template $_smarty_tpl
|
||||
* used in evaluated code
|
||||
*/
|
||||
$_smarty_tpl = $compiler->template;
|
||||
eval("\$tpl_name = @$include_file;");
|
||||
if (!isset($compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$t_hash])) {
|
||||
if (!isset($compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash])) {
|
||||
$compiler->smarty->allow_ambiguous_resources = true;
|
||||
$tpl = new $compiler->smarty->template_class ($tpl_name, $compiler->smarty, $compiler->template,
|
||||
$compiler->template->cache_id, $c_id, $_caching);
|
||||
$compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$t_hash]['uid'] = $tpl->source->uid;
|
||||
/* @var Smarty_Internal_Template $tpl */
|
||||
$tpl = new $compiler->smarty->template_class (trim($fullResourceName, "'"), $compiler->smarty,
|
||||
$compiler->template, $compiler->template->cache_id, $c_id,
|
||||
$_caching);
|
||||
$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['uid'] =
|
||||
$tpl->source->uid;
|
||||
if (!($tpl->source->handler->uncompiled) && $tpl->source->exists) {
|
||||
$tpl->compiled = new Smarty_Template_Compiled();
|
||||
$tpl->compiled->nocache_hash = $compiler->parent_compiler->template->compiled->nocache_hash;
|
||||
$tpl->loadCompiler();
|
||||
$tpl->isChild = $parameter['isChild'];
|
||||
// save unique function name
|
||||
$compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$t_hash]['func'] =
|
||||
$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['func'] =
|
||||
$tpl->compiled->unifunc = 'content_' . str_replace(array('.', ','), '_', uniqid('', true));
|
||||
// make sure whole chain gets compiled
|
||||
$tpl->mustCompile = true;
|
||||
$tpl->compiler->suppressTemplatePropertyHeader = true;
|
||||
$compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$t_hash]['nocache_hash'] =
|
||||
$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['nocache_hash'] =
|
||||
$tpl->compiled->nocache_hash;
|
||||
// get compiled code
|
||||
$compiled_code = Smarty_Internal_Extension_CodeFrame::createFunctionFrame($tpl,
|
||||
@@ -259,12 +277,10 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
||||
} else {
|
||||
$_vars = 'array()';
|
||||
}
|
||||
$this->logInclude($compiler, $include_file, $variable_template);
|
||||
$_isChild = var_export($parameter['isChild'], true);
|
||||
$update_compile_id = $compiler->template->caching && !$compiler->tag_nocache && !$compiler->nocache &&
|
||||
$_compile_id != '$_smarty_tpl->compile_id';
|
||||
if ($has_compiled_template && !$call_nocache) {
|
||||
$_output = "<?php /* Call merged included template \"" . $tpl_name . "\" */\n";
|
||||
$_output = "<?php\n";
|
||||
if ($update_compile_id) {
|
||||
$_output .= $compiler->makeNocacheCode("\$_compile_id_save[] = \$_smarty_tpl->compile_id;\n\$_smarty_tpl->compile_id = {$_compile_id};\n");
|
||||
}
|
||||
@@ -275,15 +291,15 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
||||
}
|
||||
if (isset($_assign)) {
|
||||
$_output .= "ob_start();\n";
|
||||
$_output .= "\$_smarty_tpl->_Inline->renderInline(\$_smarty_tpl, {$include_file}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_parent_scope}, {$_cache_tpl}, {$_isChild}, '{$compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$t_hash]['func']}', '{$compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$t_hash]['uid']}');\n";
|
||||
}
|
||||
$_output .= "\$_smarty_tpl->renderInline(\$_smarty_tpl->setupSubTemplate({$fullResourceName}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_parent_scope}, {$_cache_tpl}, '{$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['uid']}'), '{$compiler->parent_compiler->mergedSubTemplatesData[$hashResourceName][$t_hash]['func']}');\n";
|
||||
if (isset($_assign)) {
|
||||
$_output .= "\$_smarty_tpl->tpl_vars[$_assign] = new Smarty_Variable(ob_get_clean());\n";
|
||||
} else {
|
||||
$_output .= "\$_smarty_tpl->_Inline->renderInline(\$_smarty_tpl, {$include_file}, {$_cache_id}, {$_compile_id}, {$_caching}, {$_cache_lifetime}, {$_vars}, {$_parent_scope}, {$_cache_tpl}, {$_isChild}, '{$compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$t_hash]['func']}', '{$compiler->parent_compiler->mergedSubTemplatesData[$tpl_name][$t_hash]['uid']}');\n";
|
||||
}
|
||||
if ($update_compile_id) {
|
||||
$_output .= $compiler->makeNocacheCode("\$_smarty_tpl->compile_id = array_pop(\$_compile_id_save);\n");
|
||||
}
|
||||
$_output .= "/* End of included template \"" . $tpl_name . "\" */?>\n";
|
||||
$_output .= "?>\n";
|
||||
|
||||
return $_output;
|
||||
}
|
||||
@@ -298,10 +314,10 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
||||
// was there an assign attribute
|
||||
if (isset($_assign)) {
|
||||
$_output .= "ob_start();\n";
|
||||
$_output .= "\$_smarty_tpl->_Subtemplate->renderSubtemplate(\$_smarty_tpl, $include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope, {$_cache_tpl}, {$_isChild});\n";
|
||||
}
|
||||
$_output .= "\$_smarty_tpl->setupSubTemplate({$fullResourceName}, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope, {$_cache_tpl})->render();\n";
|
||||
if (isset($_assign)) {
|
||||
$_output .= "\$_smarty_tpl->tpl_vars[$_assign] = new Smarty_Variable(ob_get_clean());\n";
|
||||
} else {
|
||||
$_output .= "\$_smarty_tpl->_Subtemplate->renderSubtemplate(\$_smarty_tpl, $include_file, $_cache_id, $_compile_id, $_caching, $_cache_lifetime, $_vars, $_parent_scope, {$_cache_tpl}, {$_cache_tpl}, {$_isChild});\n";
|
||||
}
|
||||
if ($update_compile_id) {
|
||||
$_output .= "\$_smarty_tpl->compile_id = array_pop(\$_compile_id_save);\n";
|
||||
@@ -309,27 +325,4 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase
|
||||
$_output .= "?>\n";
|
||||
return $_output;
|
||||
}
|
||||
|
||||
/**
|
||||
* log include count
|
||||
*
|
||||
* @param \Smarty_Internal_SmartyTemplateCompiler $compiler
|
||||
* @param string $include_file
|
||||
* @param bool $variable_template
|
||||
*/
|
||||
private function logInclude(Smarty_Internal_SmartyTemplateCompiler $compiler, $include_file, $variable_template)
|
||||
{
|
||||
if ($variable_template) {
|
||||
return;
|
||||
}
|
||||
list($name, $type) = Smarty_Resource::parseResourceName(trim($include_file, '\'"'),
|
||||
$compiler->template->smarty->default_resource_type);
|
||||
if (in_array($type, array('eval', 'string'))) {
|
||||
return;
|
||||
}
|
||||
$include_name = $type . ':' . $name;
|
||||
$compiled = $compiler->parent_compiler->template->compiled;
|
||||
$compiled->includes[$include_name] =
|
||||
isset($compiled->includes[$include_name]) ? $compiled->includes[$include_name] + 1 : 1;
|
||||
}
|
||||
}
|
||||
|
@@ -1,59 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Runtime Method renderInline
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsInternal
|
||||
* @author Uwe Tews
|
||||
*/
|
||||
class Smarty_Internal_Runtime_Inline
|
||||
{
|
||||
/**
|
||||
* Template code runtime function to render inline subtemplate
|
||||
*
|
||||
* @param Smarty_Internal_Template $callerTpl
|
||||
* @param string $template template name
|
||||
* @param mixed $cache_id cache id
|
||||
* @param mixed $compile_id compile id
|
||||
* @param integer $caching cache mode
|
||||
* @param integer $cache_lifetime life time of cache data
|
||||
* @param array $data passed parameter template variables
|
||||
* @param int $parent_scope scope in which {include} should execute
|
||||
* @param bool $cache_tpl_obj cache template object
|
||||
* @param bool $isChild flag if subtemplate is an inheritance child
|
||||
* @param string $content_func name of content function
|
||||
* @param string $uid source uid
|
||||
*
|
||||
* @throws \Exception
|
||||
*/
|
||||
public function renderInline(Smarty_Internal_Template $callerTpl, $template, $cache_id, $compile_id,
|
||||
$caching, $cache_lifetime, $data, $parent_scope, $cache_tpl_obj,
|
||||
$isChild, $content_func, $uid)
|
||||
{
|
||||
// call runtime extension
|
||||
/* @var Smarty_Internal_Template $tpl */
|
||||
$tpl = $callerTpl->_Subtemplate->setupSubtemplate($callerTpl, $template, $cache_id, $compile_id,
|
||||
$caching, $cache_lifetime, $data,
|
||||
$parent_scope, $cache_tpl_obj, $uid);
|
||||
$tpl->isChild = $isChild;
|
||||
if ($callerTpl->smarty->debugging) {
|
||||
$callerTpl->smarty->_debug->start_template($tpl);
|
||||
$callerTpl->smarty->_debug->start_render($tpl);
|
||||
}
|
||||
$tpl->compiled->getRenderedTemplateCode($tpl, $content_func);
|
||||
if ($callerTpl->smarty->debugging) {
|
||||
$callerTpl->smarty->_debug->end_template($tpl);
|
||||
$callerTpl->smarty->_debug->end_render($tpl);
|
||||
}
|
||||
if ($caching == 9999 && $tpl->compiled->has_nocache_code) {
|
||||
$callerTpl->cached->hashes[$tpl->compiled->nocache_hash] = true;
|
||||
}
|
||||
if (!isset($callerTpl->_Block) && $isChild && isset($tpl->_Block) &&
|
||||
($callerTpl->isChild || !empty($callerTpl->source->components))
|
||||
) {
|
||||
$callerTpl->_Block = $tpl->_Block;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@@ -1,165 +0,0 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Runtime Method _getSubTemplate
|
||||
*
|
||||
* @package Smarty
|
||||
* @subpackage PluginsInternal
|
||||
* @author Uwe Tews
|
||||
*
|
||||
**/
|
||||
class Smarty_Internal_Runtime_Subtemplate
|
||||
{
|
||||
/**
|
||||
* Template code runtime function to get subtemplate content
|
||||
*
|
||||
* @param \Smarty_Internal_Template $callerTpl template object of caller
|
||||
* @param string $template template name
|
||||
* @param mixed $cache_id cache id
|
||||
* @param mixed $compile_id compile id
|
||||
* @param integer $caching cache mode
|
||||
* @param integer $cache_lifetime life time of cache data
|
||||
* @param array $data passed parameter template variables
|
||||
* @param int $parent_scope scope in which {include} should execute
|
||||
* @param bool $cache_tpl_obj cache template object
|
||||
* @param bool $isChild flag if subtemplate is an inheritance child
|
||||
*
|
||||
* @throws \SmartyException
|
||||
*/
|
||||
public function renderSubtemplate(Smarty_Internal_Template $callerTpl, $template, $cache_id, $compile_id, $caching,
|
||||
$cache_lifetime, $data, $parent_scope, $cache_tpl_obj, $isChild)
|
||||
{
|
||||
$tpl = $this->setupSubtemplate($callerTpl, $template, $cache_id, $compile_id, $caching, $cache_lifetime, $data,
|
||||
$parent_scope, $cache_tpl_obj);
|
||||
$tpl->isChild = $isChild;
|
||||
$tpl->render();
|
||||
if ($tpl->isChild && !isset($callerTpl->_Block) && isset($tpl->_Block) &&
|
||||
($callerTpl->isChild || !empty($callerTpl->source->components))
|
||||
) {
|
||||
$callerTpl->_Block = $tpl->_Block;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Template code runtime function to set up an inline subtemplate
|
||||
*
|
||||
* @param \Smarty_Internal_Template $callerTpl
|
||||
* @param string $template template name
|
||||
* @param mixed $cache_id cache id
|
||||
* @param mixed $compile_id compile id
|
||||
* @param integer $caching cache mode
|
||||
* @param integer $cache_lifetime life time of cache data
|
||||
* @param array $data passed parameter template variables
|
||||
* @param int $parent_scope scope in which {include} should execute
|
||||
* @param bool $cache_tpl_obj cache template object
|
||||
* @param string|null $uid source uid
|
||||
*
|
||||
* @return \Smarty_Internal_Template template object
|
||||
* @throws \SmartyException
|
||||
*/
|
||||
public function setupSubtemplate(Smarty_Internal_Template $callerTpl, $template, $cache_id, $compile_id, $caching,
|
||||
$cache_lifetime, $data, $parent_scope, $cache_tpl_obj, $uid = null)
|
||||
{
|
||||
$_templateId = isset($callerTpl->smarty->_cache['template_objects']) ?
|
||||
$callerTpl->smarty->_getTemplateId($template, $cache_id, $compile_id) : null;
|
||||
// already in template cache?
|
||||
/* @var Smarty_Internal_Template $tpl */
|
||||
if (isset($callerTpl->smarty->_cache['template_objects'][$_templateId])) {
|
||||
// clone cached template object because of possible recursive call
|
||||
$tpl = clone $callerTpl->smarty->_cache['template_objects'][$_templateId];
|
||||
$tpl->parent = $callerTpl;
|
||||
if ((bool) $tpl->caching !== (bool) $caching) {
|
||||
unset($tpl->compiled);
|
||||
}
|
||||
// get variables from calling scope
|
||||
if ($parent_scope == Smarty::SCOPE_LOCAL) {
|
||||
$tpl->tpl_vars = $callerTpl->tpl_vars;
|
||||
$tpl->config_vars = $callerTpl->config_vars;
|
||||
}
|
||||
$tpl->tpl_function = $callerTpl->tpl_function;
|
||||
//if (isset($callerTpl->_cache['inheritanceBlocks'])) {
|
||||
// $tpl->_cache['inheritanceBlocks'] = $callerTpl->_cache['inheritanceBlocks'];
|
||||
//}
|
||||
} else {
|
||||
$tpl = clone $callerTpl;
|
||||
$tpl->parent = $callerTpl;
|
||||
$tpl->isChild = false;
|
||||
if (!isset($tpl->templateId) || $tpl->templateId !== $_templateId) {
|
||||
$tpl->templateId = $_templateId;
|
||||
$tpl->template_resource = $template;
|
||||
$tpl->cache_id = $cache_id;
|
||||
$tpl->compile_id = $compile_id;
|
||||
if (isset($uid)) {
|
||||
$tpl->compiled = $callerTpl->compiled;
|
||||
if (isset($tpl->compiled->includes["{$tpl->source->type}:{$tpl->source->name}"]) &&
|
||||
$tpl->compiled->includes["{$tpl->source->type}:{$tpl->source->name}"] > 1
|
||||
) {
|
||||
$cache_tpl_obj = true;
|
||||
}
|
||||
if (isset($tpl->compiled->file_dependency[$uid])) {
|
||||
$info = $tpl->compiled->file_dependency[$uid];
|
||||
$tpl->source =
|
||||
new Smarty_Template_Source(isset($tpl->smarty->_cache['resource_handlers'][$info[2]]) ?
|
||||
$tpl->smarty->_cache['resource_handlers'][$info[2]] :
|
||||
Smarty_Resource::load($tpl->smarty, $info[2]), $tpl->smarty,
|
||||
$info[0], $info[2], $info[0]);
|
||||
$tpl->source->filepath = $info[0];
|
||||
$tpl->source->timestamp = $info[1];
|
||||
$tpl->source->exist = true;
|
||||
$tpl->source->uid = $uid;
|
||||
} else {
|
||||
$tpl->source = null;
|
||||
}
|
||||
} else {
|
||||
$tpl->source = null;
|
||||
unset($tpl->compiled);
|
||||
}
|
||||
if (!isset($tpl->source)) {
|
||||
$tpl->source = Smarty_Template_Source::load($tpl);
|
||||
}
|
||||
unset($tpl->cached);
|
||||
// check if template object should be cached
|
||||
if (!$tpl->source->handler->recompiled && (isset($tpl->parent->templateId) &&
|
||||
isset($tpl->smarty->_cache['template_objects'][$tpl->parent->templateId]) ||
|
||||
($cache_tpl_obj && $tpl->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_AUTOMATIC) ||
|
||||
$tpl->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_ON)
|
||||
) {
|
||||
$tpl->smarty->_cache['template_objects'][$tpl->_getTemplateId()] = $tpl;
|
||||
}
|
||||
}
|
||||
}
|
||||
$tpl->caching = $caching;
|
||||
$tpl->cache_lifetime = $cache_lifetime;
|
||||
if ($caching == 9999) {
|
||||
$tpl->cached = $callerTpl->cached;
|
||||
}
|
||||
// get variables from calling scope
|
||||
if ($parent_scope != Smarty::SCOPE_LOCAL) {
|
||||
if ($parent_scope == Smarty::SCOPE_PARENT) {
|
||||
$tpl->tpl_vars = &$callerTpl->tpl_vars;
|
||||
$tpl->config_vars = &$callerTpl->config_vars;
|
||||
} elseif ($parent_scope == Smarty::SCOPE_GLOBAL) {
|
||||
$tpl->tpl_vars = &Smarty::$global_tpl_vars;
|
||||
$tpl->config_vars = $callerTpl->config_vars;
|
||||
} elseif ($parent_scope == Smarty::SCOPE_ROOT) {
|
||||
$ptr = $tpl->parent;
|
||||
while (!empty($ptr->parent)) {
|
||||
$ptr = $ptr->parent;
|
||||
}
|
||||
$tpl->tpl_vars = &$ptr->tpl_vars;
|
||||
$tpl->config_vars = &$ptr->config_vars;
|
||||
} else {
|
||||
$tpl->tpl_vars = $callerTpl->tpl_vars;
|
||||
$tpl->config_vars = $callerTpl->config_vars;
|
||||
}
|
||||
}
|
||||
|
||||
if (!empty($data)) {
|
||||
// set up variable values
|
||||
foreach ($data as $_key => $_val) {
|
||||
$tpl->tpl_vars[$_key] = new Smarty_Variable($_val);
|
||||
}
|
||||
}
|
||||
return $tpl;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user