- more optimizations of template processing

This commit is contained in:
uwetews
2015-10-24 22:43:19 +02:00
parent 4ea4d1ff41
commit 50760c794c
8 changed files with 146 additions and 149 deletions

View File

@@ -1,8 +1,6 @@
 ===== 3.1.28-dev===== (xx.xx.2015)
24.10.2015
- new extension handler to load functions when called
- improve recovery from ivalid compiled template code
- improve autoloader speed
- more optimizations of template processing
21.10.2015
- move some code into runtime extensions

View File

@@ -88,17 +88,20 @@ if (!class_exists('Smarty_Autoloader', false)) {
* Load always needed external class files
*/
if (!class_exists('Smarty_Internal_Data', false)) {
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_data.php';
if (false) {
if (!class_exists('Smarty_Internal_Data', false)) {
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_data.php';
}
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_extension_handler.php';
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_templatebase.php';
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_template.php';
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_resource.php';
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_resource_file.php';
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_variable.php';
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_template_source.php';
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_template_resource_base.php';
}
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_extension_handler.php';
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_templatebase.php';
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_template.php';
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_resource.php';
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_internal_resource_file.php';
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_variable.php';
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_template_source.php';
require_once SMARTY_SYSPLUGINS_DIR . 'smarty_template_resource_base.php';
/**
* This is the main Smarty class
@@ -120,7 +123,7 @@ class Smarty extends Smarty_Internal_TemplateBase
/**
* smarty version
*/
const SMARTY_VERSION = '3.1.28-dev/71';
const SMARTY_VERSION = '3.1.28-dev/72';
/**
* define variable scopes
@@ -1119,15 +1122,16 @@ class Smarty extends Smarty_Internal_TemplateBase
*
* @return string
*/
public function _getTemplateId($template_name, $cache_id = null, $compile_id = null)
public function _getTemplateId($template_name, $cache_id = null, $compile_id = null, $caching = null)
{
$cache_id = $cache_id === null ? $this->cache_id : $cache_id;
$compile_id = $compile_id === null ? $this->compile_id : $compile_id;
$caching = (int) ($caching === null ? $this->caching : $caching);
if ($this->allow_ambiguous_resources) {
$_templateId = Smarty_Resource::getUniqueTemplateName($this, $template_name) . "#{$cache_id}#{$compile_id}";
$_templateId = Smarty_Resource::getUniqueTemplateName($this, $template_name) . "#{$cache_id}#{$compile_id}#{$caching}";
} else {
$_templateId = $this->_joined_template_dir . "#{$template_name}#{$cache_id}#{$compile_id}";
$_templateId = $this->_joined_template_dir . "#{$template_name}#{$cache_id}#{$compile_id}#{$caching}";
}
if (isset($_templateId[150])) {
$_templateId = sha1($_templateId);

View File

@@ -174,6 +174,27 @@ class Smarty_Internal_Data
return $this->ext->getTemplateVars->getTemplateVars($this, $varName, $_ptr, $searchParents);
}
/**
* Follow the parent chain an merge template and config variables
*
* @param \Smarty_Internal_Data|null $data
*/
public function _mergeVars(Smarty_Internal_Data $data = null) {
if (isset($data)) {
if (!empty($this->tpl_vars)) {
$data->tpl_vars = array_merge($this->tpl_vars, $data->tpl_vars);
}
if (!empty($this->config_vars)) {
$data->config_vars = array_merge($this->config_vars, $data->config_vars);
}
} else {
$data = $this;
}
if (isset($this->parent)) {
$this->parent->_mergeVars($data);
}
}
/**
* Handle unknown class methods
*

View File

@@ -8,7 +8,7 @@
* @author Uwe Tews
*
**/
class Smarty_Internal_Runtime_Inline extends Smarty_Internal_Runtime_SubTemplate
class Smarty_Internal_Runtime_Inline
{
/**
@@ -31,8 +31,8 @@ class Smarty_Internal_Runtime_Inline extends Smarty_Internal_Runtime_SubTemplate
public function render(\Smarty_Internal_Template $parent, $template, $cache_id, $compile_id, $caching,
$cache_lifetime, $data, $scope, $forceTplCache, $uid, $content_func)
{
$tpl = $this->setupSubTemplate($parent, $template, $cache_id, $compile_id, $caching, $cache_lifetime, $data,
$scope, $uid);
$tpl = $parent->smarty->ext->_subTemplate->setupSubTemplate($parent, $template, $cache_id, $compile_id, $caching, $cache_lifetime, $data,
$scope, $forceTplCache, $uid);
if ($parent->smarty->debugging) {
$parent->smarty->_debug->start_template($tpl);
$parent->smarty->_debug->start_render($tpl);
@@ -45,7 +45,6 @@ class Smarty_Internal_Runtime_Inline extends Smarty_Internal_Runtime_SubTemplate
if ($tpl->caching == 9999 && $tpl->compiled->has_nocache_code) {
$parent->cached->hashes[$tpl->compiled->nocache_hash] = true;
}
$this->updateTemplateCache($tpl, $forceTplCache);
}
/**
@@ -56,22 +55,31 @@ class Smarty_Internal_Runtime_Inline extends Smarty_Internal_Runtime_SubTemplate
*
* @throws \SmartyException
*/
public function setSourceByUid(Smarty_Internal_Template $tpl, $uid)
public function setSource(Smarty_Internal_Template $tpl, $uid = null)
{
// inline templates have same compiled resource
$tpl->compiled = $tpl->parent->compiled;
if (isset($tpl->compiled->file_dependency[$uid])) {
list($filepath, $timestamp, $resource) = $tpl->compiled->file_dependency[$uid];
$tpl->source = new Smarty_Template_Source(isset($tpl->smarty->_cache['resource_handlers'][$resource]) ?
$tpl->smarty->_cache['resource_handlers'][$resource] :
Smarty_Resource::load($tpl->smarty, $resource), $tpl->smarty,
$filepath, $resource, $filepath);
$tpl->source->filepath = $filepath;
$tpl->source->timestamp = $timestamp;
$tpl->source->exists = true;
$tpl->source->uid = $uid;
// $uid is set if template is inline
if (isset($uid)) {
// inline templates have same compiled resource
$tpl->compiled = $tpl->parent->compiled;
if (isset($tpl->compiled->file_dependency[$uid])) {
list($filepath, $timestamp, $resource) = $tpl->compiled->file_dependency[$uid];
$tpl->source = new Smarty_Template_Source(isset($tpl->smarty->_cache['resource_handlers'][$resource]) ?
$tpl->smarty->_cache['resource_handlers'][$resource] :
Smarty_Resource::load($tpl->smarty, $resource),
$tpl->smarty, $filepath, $resource, $filepath);
$tpl->source->filepath = $filepath;
$tpl->source->timestamp = $timestamp;
$tpl->source->exists = 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);
}
}
}

View File

@@ -11,6 +11,8 @@
class Smarty_Internal_Runtime_SubTemplate
{
public $tplObjects = array();
public $subTplInfo = array();
/**
* Runtime function to render subtemplate
*
@@ -27,11 +29,8 @@ class Smarty_Internal_Runtime_SubTemplate
*/
public function render(Smarty_Internal_Template $parent, $template, $cache_id, $compile_id, $caching,
$cache_lifetime, $data, $scope, $forceTplCache)
{
$tpl = $this->setupSubTemplate($parent, $template, $cache_id, $compile_id, $caching, $cache_lifetime, $data,
$scope);
$tpl->render();
$this->updateTemplateCache($tpl, $forceTplCache);
{$this->setupSubTemplate($parent, $template, $cache_id, $compile_id, $caching, $cache_lifetime, $data,
$scope, $forceTplCache)->render();
}
/**
@@ -45,38 +44,38 @@ class Smarty_Internal_Runtime_SubTemplate
* @param integer $cache_lifetime life time of cache data
* @param array $data passed parameter template variables
* @param int $scope scope in which {include} should execute
* @param $forceTplCache
* @param string|null $uid source uid
*
* @return \Smarty_Internal_Template template object
* @throws \SmartyException
*/
public function setupSubTemplate(Smarty_Internal_Template $parent, $template, $cache_id, $compile_id, $caching,
$cache_lifetime, $data, $scope, $uid = null)
$cache_lifetime, $data, $scope, $forceTplCache, $uid = null)
{
// if there are cached template objects calculate $templateID
$_templateId = isset($parent->smarty->_cache['template_objects']) ?
$parent->smarty->_getTemplateId($template, $cache_id, $compile_id) : null;
$_templateId = !empty($this->tplObjects) ?
$parent->smarty->_getTemplateId($template, $cache_id, $compile_id, $caching) : null;
// already in template cache?
/* @var Smarty_Internal_Template $tpl */
if (isset($parent->smarty->_cache['template_objects'][$_templateId])) {
if (isset($this->tplObjects[$_templateId])) {
// clone cached template object because of possible recursive call
$tpl = clone $parent->smarty->_cache['template_objects'][$_templateId];
$tpl = clone $this->tplObjects[$_templateId];
$tpl->parent = $parent;
// if $caching mode changed the compiled resource is invalid
if ((bool) $tpl->caching !== (bool) $caching) {
unset($tpl->compiled);
}
// get variables from calling scope
if ($scope == Smarty::SCOPE_LOCAL) {
if ($scope == Smarty::SCOPE_LOCAL && $tpl->scope == Smarty::SCOPE_LOCAL) {
$tpl->tpl_vars = $parent->tpl_vars;
$tpl->config_vars = $parent->config_vars;
}
$tpl->tpl_function = $parent->tpl_function;
// copy inheritance object?
if (isset($parent->_inheritance)) {
$tpl->_inheritance = $parent->_inheritance;
if (isset($parent->ext->_inheritance)) {
$tpl->ext->_inheritance = $parent->ext->_inheritance;
} else {
unset($tpl->_inheritance);
unset($tpl->ext->_inheritance);
}
} else {
$tpl = clone $parent;
@@ -86,15 +85,10 @@ class Smarty_Internal_Runtime_SubTemplate
$tpl->template_resource = $template;
$tpl->cache_id = $cache_id;
$tpl->compile_id = $compile_id;
// $uid is set if template is inline
if (isset($uid)) {
$this->setSourceByUid($tpl, $uid);
$tpl->ext->_inline->setSource($tpl, $uid);
} else {
$tpl->source = null;
unset($tpl->compiled);
}
if (!isset($tpl->source)) {
$tpl->source = Smarty_Template_Source::load($tpl);
$this->setSource($tpl, $uid);
}
unset($tpl->cached);
}
@@ -107,6 +101,7 @@ class Smarty_Internal_Runtime_SubTemplate
// get variables from calling scope
if ($scope != $tpl->scope) {
if ($tpl->scope != Smarty::SCOPE_LOCAL) {
//We must get rid of pointers
unset($tpl->tpl_vars, $tpl->config_vars);
$tpl->tpl_vars = array();
$tpl->config_vars = array();
@@ -131,6 +126,21 @@ class Smarty_Internal_Runtime_SubTemplate
$tpl->scope = $scope;
}
if (!isset($this->tplObjects[$tpl->_getTemplateId()]) &&
!$tpl->source->handler->recompiled
) {
// if template is called multiple times set flag to to cache template objects
$forceTplCache = $forceTplCache ||
(isset($this->subTplInfo[$tpl->template_resource]) && $this->subTplInfo[$tpl->template_resource] > 1);
// check if template object should be cached
if ($tpl->parent->_objType == 2 && isset($this->tplObjects[$tpl->parent->templateId]) ||
($forceTplCache && $tpl->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_AUTOMATIC) ||
($tpl->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_ON)
) {
$this->tplObjects[$tpl->_getTemplateId()] = $tpl;
}
}
if (!empty($data)) {
// set up variable values
foreach ($data as $_key => $_val) {
@@ -140,30 +150,37 @@ class Smarty_Internal_Runtime_SubTemplate
return $tpl;
}
public function updateTemplateCache(Smarty_Internal_Template $tpl, $forceTplCache)
/**
* Set source object of inline template by $uid
*
* @param \Smarty_Internal_Template $tpl
* @param string $uid
*
* @throws \SmartyException
*/
public function setSource(Smarty_Internal_Template $tpl, $uid = null)
{
if (isset($tpl->smarty->_cache['template_objects'][$tpl->_getTemplateId()]) ||
$tpl->source->handler->recompiled
) {
return;
}
// if template is called multiple times set flag to to cache template objects
$forceTplCache = $forceTplCache || (isset($tpl->compiled->includes[$tpl->template_resource]) &&
$tpl->compiled->includes[$tpl->template_resource] > 1);
// check if template object should be cached
if ((isset($tpl->parent->templateId) &&
isset($tpl->smarty->_cache['template_objects'][$tpl->parent->templateId]) ||
($forceTplCache && $tpl->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_AUTOMATIC) ||
$tpl->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_ON)
) {
$tpl->parent = null;
if ($tpl->scope != Smarty::SCOPE_LOCAL) {
unset($tpl->tpl_vars, $tpl->config_vars);
$tpl->scope = Smarty::SCOPE_LOCAL;
}
$tpl->tpl_vars = array();
$tpl->config_vars = array();
$tpl->smarty->_cache['template_objects'][$tpl->_getTemplateId()] = $tpl;
//load source
$tpl->source = null;
unset($tpl->compiled);
if (!isset($tpl->source)) {
$tpl->source = Smarty_Template_Source::load($tpl);
}
}
/**
* Get called subtemplates and its call count from compiled template
*
* @param \Smarty_Internal_Template $tpl
*/
public function registerSubTemplates(Smarty_Internal_Template $tpl) {
foreach ($tpl->compiled->includes as $name => $count) {
if (isset($this->subTplInfo[$name])) {
$this->subTplInfo[$name] += $count;
} else {
$this->subTplInfo[$name] = $count;
}
}
}
}

View File

@@ -123,7 +123,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
* @throws SmartyException
* @return string rendered template output
*/
public function render($merge_tpl_vars = false, $no_output_filter = true, $display = null)
public function render($no_output_filter = true, $display = null)
{
$parentIsTpl = isset($this->parent) && $this->parent->_objType == 2;
if ($this->smarty->debugging) {
@@ -138,36 +138,6 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
}
throw new SmartyException("Unable to load template {$this->source->type} '{$this->source->name}'{$parent_resource}");
}
$save_tpl_vars = null;
$save_config_vars = null;
// merge all variable scopes into template
if ($merge_tpl_vars) {
// save local variables
$save_tpl_vars = $this->tpl_vars;
$save_config_vars = $this->config_vars;
$ptr_array = array($this);
$ptr = $this;
while (isset($ptr->parent)) {
$ptr_array[] = $ptr = $ptr->parent;
}
$ptr_array = array_reverse($ptr_array);
$parent_ptr = reset($ptr_array);
$tpl_vars = $parent_ptr->tpl_vars;
$config_vars = $parent_ptr->config_vars;
while ($parent_ptr = next($ptr_array)) {
if (!empty($parent_ptr->tpl_vars)) {
$tpl_vars = array_merge($tpl_vars, $parent_ptr->tpl_vars);
}
if (!empty($parent_ptr->config_vars)) {
$config_vars = array_merge($config_vars, $parent_ptr->config_vars);
}
}
if (!empty(Smarty::$global_tpl_vars)) {
$tpl_vars = array_merge(Smarty::$global_tpl_vars, $tpl_vars);
}
$this->tpl_vars = $tpl_vars;
$this->config_vars = $config_vars;
}
// check URL debugging control
if (!$this->smarty->debugging && $this->smarty->debugging_ctrl == 'URL') {
$this->smarty->_debug->debugUrl($this);
@@ -213,18 +183,8 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
// debug output
$this->smarty->_debug->display_debug($this, true);
}
if ($merge_tpl_vars) {
// restore local variables
$this->tpl_vars = $save_tpl_vars;
$this->config_vars = $save_config_vars;
}
return '';
} else {
if ($merge_tpl_vars) {
// restore local variables
$this->tpl_vars = $save_tpl_vars;
$this->config_vars = $save_config_vars;
}
if ($this->smarty->debugging) {
$this->smarty->_debug->end_template($this);
if ($this->smarty->debugging == 2 and $display === false) {

View File

@@ -88,18 +88,14 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
* @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 object $parent next higher level of Smarty variables
* @param bool $display not used - left for BC
* @param bool $merge_tpl_vars not used - left for BC
* @param bool $no_output_filter not used - left for BC
*
* @throws Exception
* @throws SmartyException
* @return string rendered template output
*/
public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null, $display = false,
$merge_tpl_vars = true, $no_output_filter = false)
public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null)
{
$result = $this->_execute($template, $cache_id, $compile_id, $parent, 'fetch');
$result = $this->_execute($template, $cache_id, $compile_id, $parent, 0);
return $result === null ? ob_get_clean() : $result;
}
@@ -114,7 +110,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
public function display($template = null, $cache_id = null, $compile_id = null, $parent = null)
{
// display template
$this->_execute($template, $cache_id, $compile_id, $parent, 'display');
$this->_execute($template, $cache_id, $compile_id, $parent, 1);
}
/**
@@ -132,7 +128,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
*/
public function isCached($template = null, $cache_id = null, $compile_id = null, $parent = null)
{
return $this->_execute($template, $cache_id, $compile_id, $parent, 'isCached');
return $this->_execute($template, $cache_id, $compile_id, $parent, 2);
}
/**
@@ -142,7 +138,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
* @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 object $parent next higher level of Smarty variables
* @param string $function function name
* @param string $function function type 0 = fetch, 1 = display, 2 = isCache
*
* @return mixed
* @throws \Exception
@@ -177,7 +173,7 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
$_smarty_old_error_level =
($this->_objType == 1 && isset($smarty->error_reporting)) ? error_reporting($smarty->error_reporting) :
null;
if ($function == 'isCached') {
if ($function == 2) {
if ($template->caching) {
// return cache status of template
if (!isset($template->cached)) {
@@ -190,7 +186,16 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
}
} else {
ob_start();
$result = $template->render(true, false, $function == 'display');
$save_tpl_vars = $template->tpl_vars;
$save_config_vars = $template->config_vars;
$template->_mergeVars();
if (!empty(Smarty::$global_tpl_vars)) {
$template->tpl_vars = array_merge(Smarty::$global_tpl_vars, $template->tpl_vars);
}
$result = $template->render(false, $function);
// restore local variables
$template->tpl_vars = $save_tpl_vars;
$template->config_vars = $save_config_vars;
}
if (isset($_smarty_old_error_level)) {
error_reporting($_smarty_old_error_level);

View File

@@ -152,24 +152,8 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base
$_template->smarty->compile_check = $compileCheck;
}
}
if (isset($_template->parent) && isset($_template->parent->compiled) &&
!empty($_template->parent->compiled->includes) &&
$_template->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_AUTOMATIC &&
!$_template->source->handler->recompiled && $_template->source->type != 'string' &&
(!isset($_template->smarty->_cache['template_objects']) ||
!isset($_template->smarty->_cache['template_objects'][$_template->_getTemplateId()]))
) {
foreach ($_template->parent->compiled->includes as $key => $count) {
$_template->compiled->includes[$key] =
isset($_template->compiled->includes[$key]) ? $_template->compiled->includes[$key] + $count :
$count;
}
$key = $_template->source->type . ':' . $_template->source->name;
if (isset($_template->compiled->includes[$key]) && $_template->compiled->includes[$key] > 1) {
$_template->smarty->_cache['template_objects'][isset($_template->templateId) ? $_template->templateId :
$_template->_getTemplateId()] = $_template;
}
}
$_template->smarty->ext->_subTemplate->registerSubTemplates($_template);
$this->processed = true;
}