- optimize rendering

This commit is contained in:
uwetews
2015-08-23 01:25:57 +02:00
parent 329cd6ec4d
commit 6a26393099
14 changed files with 401 additions and 358 deletions

View File

@@ -7,6 +7,7 @@
- use output buffers for better performance and less memory usage
- optimize nocache hash processing
- remove not really needed properties
- optimize rendering
06.08.2015
- avoid possible circular object references caused by parser/lexer objects

View File

@@ -756,67 +756,6 @@ class Smarty extends Smarty_Internal_TemplateBase
}
}
/**
* fetches a rendered Smarty template
*
* @param string $template the resource handle of the template file or template object
* @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 true: display, false: fetch
* @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, $cache_id = null, $compile_id = null, $parent = null, $display = false, $merge_tpl_vars = true, $no_output_filter = false)
{
if ($cache_id !== null && is_object($cache_id)) {
$parent = $cache_id;
$cache_id = null;
}
if ($parent === null) {
$parent = $this;
}
// get template object
$_template = is_object($template) ? $template : $this->createTemplate($template, $cache_id, $compile_id, $parent, false);
// set caching in template object
$_template->caching = $this->caching;
// fetch template content
$level = ob_get_level();
try {
$_smarty_old_error_level = isset($this->error_reporting) ? error_reporting($this->error_reporting) : null;
ob_start();
$result = $_template->render(true, false, $display);
if (isset($_smarty_old_error_level)) {
error_reporting($_smarty_old_error_level);
}
return $result === null ? ob_get_clean() : $result;
}
catch (Exception $e) {
while (ob_get_level() > $level) {
ob_end_clean();
}
throw $e;
}
}
/**
* displays a Smarty template
*
* @param string $template the resource handle of the template file or template object
* @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
*/
public function display($template, $cache_id = null, $compile_id = null, $parent = null)
{
// display template
$this->fetch($template, $cache_id, $compile_id, $parent, true);
}
/**
* Check if a template resource exists
*
@@ -1180,10 +1119,20 @@ class Smarty extends Smarty_Internal_TemplateBase
} else {
$data = null;
}
/* var Smarty $tpl */
$tpl = new $this->template_class($template, $this, $parent, $cache_id, $compile_id);
$_templateId = $this->_getTemplateId($template, $cache_id, $compile_id);
if (isset($this->_cache['isCached'][$_templateId])) {
$tpl = $do_clone ? clone $this->_cache['isCached'][$_templateId] : $this->_cache['isCached'][$_templateId];
$tpl->parent = $parent;
$tpl->tpl_vars = array();
$tpl->config_vars = array();
} else {
/* @var Smarty_Internal_Template $tpl */
$tpl = new $this->template_class($template, $this, $parent, $cache_id, $compile_id, null, null, $_templateId);
}
if ($do_clone) {
$tpl->smarty = clone $tpl->smarty;
} elseif ($parent === null) {
$tpl->parent = $this;
}
// fill data if present
if (!empty($data) && is_array($data)) {
@@ -1214,6 +1163,31 @@ class Smarty extends Smarty_Internal_TemplateBase
return Smarty_Internal_Extension_LoadPlugin::loadPlugin($this, $plugin_name, $check);
}
/**
* Get unique template id
*
* @param string $template_name
* @param null|mixed $cache_id
* @param null|mixed $compile_id
*
* @return string
*/
public function _getTemplateId($template_name, $cache_id = null, $compile_id = null)
{
$cache_id = $cache_id === null ? $this->cache_id : $cache_id;
$compile_id = $compile_id === null ? $this->compile_id : $compile_id;
if ($this->allow_ambiguous_resources) {
$_templateId = Smarty_Resource::getUniqueTemplateName($this, $template_name) . "#{$cache_id}#{$compile_id}";
} else {
$_templateId = $this->_joined_template_dir . "#{$template_name}#{$cache_id}#{$compile_id}";
}
if (isset($_templateId[150])) {
$_templateId = sha1($_templateId);
}
return $_templateId;
}
/**
* Normalize path
* - remove /./ and /../

View File

@@ -45,14 +45,8 @@ class Smarty_Internal_Method_ConfigLoad
$confObj->source->config_sections = $sections;
$confObj->source->scope = $scope;
$confObj->compiled = Smarty_Template_Compiled::load($confObj);
if ($confObj->smarty->debugging) {
$confObj->smarty->_debug->start_render($confObj);
}
$confObj->compiled->render($confObj);
if ($confObj->smarty->debugging) {
$confObj->smarty->_debug->end_render($confObj);
}
if ($data instanceof Smarty_Internal_Template) {
if ($data->_objType == 2) {
$data->compiled->file_dependency[$confObj->source->uid] = array($confObj->source->filepath,
$confObj->source->getTimeStamp(),
$confObj->source->type);

View File

@@ -24,6 +24,14 @@ class Smarty_Internal_Resource_Php extends Smarty_Internal_Resource_File
*/
protected $short_open_tag;
/**
* Resource does implement populateCompiledFilepath() method
*
* @var bool
*/
public $hasCompiledHandler = true;
/**
* Create a new PHP Resource
@@ -64,7 +72,7 @@ class Smarty_Internal_Resource_Php extends Smarty_Internal_Resource_File
throw new SmartyException("PHP templates are disabled");
}
if (!$source->exists) {
if ($_template->parent instanceof Smarty_Internal_Template) {
if ($_template->parent->_objType == 2) {
$parent_resource = " in '{$_template->parent->template_resource}'";
} else {
$parent_resource = '';

View File

@@ -137,65 +137,14 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
// Template resource
$this->template_resource = $template_resource;
$this->source = Smarty_Template_Source::load($this);
$this->templateId = isset($_templateId) ? $_templateId : $this->getTemplateId($template_resource, $this->cache_id, $this->compile_id);
$this->templateId = isset($_templateId) ? $_templateId : $this->smarty->_getTemplateId($template_resource, $this->cache_id, $this->compile_id);
// copy block data of template inheritance
if ($this->parent instanceof Smarty_Internal_Template) {
if (isset($this->parent) && $this->parent->_objType == 2) {
$this->block_data = $this->parent->block_data;
}
}
/**
* fetches rendered template
*
* @param string $template the resource handle of the template file or template object
* @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 true: display, false: fetch
*
* @return string
* @throws \Exception
*/
public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null, $_display = false)
{
if (isset($template)) {
return $this->smarty->fetch($template, $cache_id, $compile_id, $parent, $_display);
} else {
// fetch template content
$level = ob_get_level();
try {
$_smarty_old_error_level = isset($this->smarty->error_reporting) ? error_reporting($this->smarty->error_reporting) : null;
ob_start();
$result = $this->render(true, false, $_display);
if (isset($_smarty_old_error_level)) {
error_reporting($_smarty_old_error_level);
}
return $result === null ? ob_get_clean() : $result;
}
catch (Exception $e) {
while (ob_get_level() > $level) {
ob_end_clean();
}
throw $e;
}
}
}
/**
* displays a Smarty template
*
* @param string $template the resource handle of the template file or template object
* @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
*
* @return string
*/
public function display($template = null, $cache_id = null, $compile_id = null, $parent = null)
{
$this->fetch($template, $cache_id, $compile_id, $parent, true);
}
/**
* render template
*
@@ -209,7 +158,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
*/
public function render($merge_tpl_vars = false, $no_output_filter = true, $display = null)
{
$parentIsTpl = $this->parent instanceof Smarty_Internal_Template;
$parentIsTpl = isset($this->parent) && $this->parent->_objType == 2;
if ($this->smarty->debugging) {
$this->smarty->_debug->start_template($this, $display);
}
@@ -252,70 +201,30 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
$this->tpl_vars = $tpl_vars;
$this->config_vars = $config_vars;
}
// check URL debugging control
// check URL debugging control
if (!$this->smarty->debugging && $this->smarty->debugging_ctrl == 'URL') {
$this->smarty->_debug->debugUrl($this);
}
// disable caching for evaluated code
if ($this->source->recompiled) {
$this->caching = false;
}
// read from cache or render
$isCacheTpl = $this->caching == Smarty::CACHING_LIFETIME_CURRENT ||
$this->caching == Smarty::CACHING_LIFETIME_SAVED;
if ($isCacheTpl) {
if (!isset($this->cached)) {
$this->loadCached();
if ($this->source->uncompiled) {
$this->source->render($this);
} else {
// disable caching for evaluated code
if ($this->source->recompiled) {
$this->caching = false;
}
$this->cached->isCached($this);
}
if (!($isCacheTpl) || !$this->cached->valid) {
// render template (not loaded and not in cache)
if ($this->smarty->debugging) {
$this->smarty->_debug->start_render($this);
}
if (!$this->source->uncompiled) {
// render compiled code
// read from cache or render
$isCacheTpl = $this->caching == Smarty::CACHING_LIFETIME_CURRENT ||
$this->caching == Smarty::CACHING_LIFETIME_SAVED;
if ($isCacheTpl) {
if (!isset($this->cached)) {
$this->loadCached();
}
$this->cached->render($this, $no_output_filter);
} else {
if (!isset($this->compiled)) {
$this->loadCompiled();
}
$this->compiled->render($this);
} else {
$this->source->renderUncompiled($this);
}
if ($parentIsTpl && !empty($this->tpl_function)) {
$this->parent->tpl_function = array_merge($this->parent->tpl_function, $this->tpl_function);
}
if ($this->smarty->debugging) {
$this->smarty->_debug->end_render($this);
}
// write to cache when necessary
if (!$this->source->recompiled && $isCacheTpl) {
if ($this->smarty->debugging) {
$this->smarty->_debug->start_cache($this);
}
$this->cached->updateCache($this, $no_output_filter);
$compile_check = $this->smarty->compile_check;
$this->smarty->compile_check = false;
if ($parentIsTpl) {
$this->compiled->unifunc = $this->parent->compiled->unifunc;
}
if (!$this->cached->processed) {
$this->cached->process($this, true);
}
$this->smarty->compile_check = $compile_check;
$this->getRenderedTemplateCode($this->cached->unifunc);
if ($this->smarty->debugging) {
$this->smarty->_debug->end_cache($this);
}
}
} else {
if ($this->smarty->debugging) {
$this->smarty->_debug->start_cache($this);
}
$this->cached->render($this);
if ($this->smarty->debugging) {
$this->smarty->_debug->end_cache($this);
}
}
$content = null;
@@ -359,7 +268,9 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
}
}
if ($parentIsTpl) {
$this->parent->tpl_function = array_merge($this->parent->tpl_function, $this->tpl_function);
if (!empty($this->tpl_function)) {
$this->parent->tpl_function = array_merge($this->parent->tpl_function, $this->tpl_function);
}
foreach ($this->compiled->required_plugins as $code => $tmp1) {
foreach ($tmp1 as $name => $tmp) {
foreach ($tmp as $type => $data) {
@@ -369,7 +280,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
}
}
// return cache content
return $content === null ? null: $content;
return $content === null ? null : $content;
}
}
@@ -439,30 +350,6 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
return $this->cached->writeCachedContent($this, $content);
}
/**
* Get unique template id
*
* @param string $template_name
* @param null|mixed $cache_id
* @param null|mixed $compile_id
*
* @return string
*/
public function getTemplateId($template_name, $cache_id = null, $compile_id = null)
{
$cache_id = isset($cache_id) ? $cache_id : $this->cache_id;
$compile_id = isset($compile_id) ? $compile_id : $this->compile_id;
if ($this->smarty->allow_ambiguous_resources) {
$_templateId = Smarty_Resource::getUniqueTemplateName($this, $template_name) . "#{$cache_id}#{$compile_id}";
} else {
$_templateId = $this->smarty->_joined_template_dir . "#{$template_name}#{$cache_id}#{$compile_id}";
}
if (isset($_templateId[150])) {
$_templateId = sha1($_templateId);
}
return $_templateId;
}
/**
* Template code runtime function to get subtemplate content
*
@@ -500,7 +387,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
*/
public function setupSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $cache_tpl_obj)
{
$_templateId = $this->getTemplateId($template, $cache_id, $compile_id);
$_templateId = $this->smarty->_getTemplateId($template, $cache_id, $compile_id);
// already in template cache?
/* @var Smarty_Internal_Template $tpl */
if (isset($this->smarty->template_objects[$_templateId])) {
@@ -510,41 +397,51 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
if ((bool) $tpl->caching !== (bool) $caching) {
unset($tpl->compiled);
}
$tpl->caching = $caching;
$tpl->cache_lifetime = $cache_lifetime;
if ($parent_scope = Smarty::SCOPE_LOCAL) {
$tpl->tpl_vars = $this->tpl_vars;
$tpl->config_vars = $this->config_vars;
}
$tpl->tpl_function = $this->tpl_function;
} else {
$tpl = new $this->smarty->template_class($template, $this->smarty, $this, $cache_id, $compile_id, $caching, $cache_lifetime, $_templateId);
}
if (!$tpl->source->recompiled && !isset($this->smarty->template_objects[$_templateId]) &&
(isset($this->smarty->template_objects[$this->templateId]) ||
($cache_tpl_obj && $this->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_AUTOMATIC) ||
$this->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_ON)
) {
$this->smarty->template_objects[$_templateId] = $tpl;
$tpl = clone $this;
$tpl->parent = $this;
if ($tpl->templateId !== $_templateId) {
$tpl->templateId = $_templateId;
$tpl->template_resource = $template;
$tpl->cache_id = $cache_id;
$tpl->compile_id = $compile_id;
$tpl->source = Smarty_Template_Source::load($tpl);
unset($tpl->compiled, $tpl->cached);
$tpl->cacheTpl($cache_tpl_obj);
}
}
$tpl->caching = $caching;
$tpl->cache_lifetime = $cache_lifetime;
if ($caching == 9999) {
$tpl->cached = $this->cached;
}
// get variables from calling scope
if ($parent_scope == Smarty::SCOPE_LOCAL) {
$tpl->tpl_vars = $this->tpl_vars;
} elseif ($parent_scope == Smarty::SCOPE_PARENT) {
$tpl->tpl_vars = &$this->tpl_vars;
} elseif ($parent_scope == Smarty::SCOPE_GLOBAL) {
$tpl->tpl_vars = &Smarty::$global_tpl_vars;
} elseif (($scope_ptr = $this->getScopePointer($parent_scope)) == null) {
$tpl->tpl_vars = &$this->tpl_vars;
} else {
$tpl->tpl_vars = &$scope_ptr->tpl_vars;
if ($parent_scope != Smarty::SCOPE_LOCAL) {
if ($parent_scope == Smarty::SCOPE_PARENT) {
$tpl->tpl_vars = &$this->tpl_vars;
$tpl->config_vars = &$this->config_vars;
} elseif ($parent_scope == Smarty::SCOPE_GLOBAL) {
$tpl->tpl_vars = &Smarty::$global_tpl_vars;
$tpl->config_vars = $this->config_vars;
} elseif (($scope_ptr = $this->getScopePointer($parent_scope)) == null) {
$tpl->tpl_vars = &$this->tpl_vars;
$tpl->config_vars = &$this->config_vars;
} else {
$tpl->tpl_vars = &$scope_ptr->tpl_vars;
$tpl->config_vars = &$scope_ptr->$this->config_vars;
}
}
$tpl->config_vars = $this->config_vars;
if (!empty($data)) {
// set up variable values
foreach ($data as $_key => $_val) {
$tpl->tpl_vars[$_key] = new Smarty_Variable($_val);
}
}
$tpl->tpl_function = $this->tpl_function;
return $tpl;
}
@@ -570,7 +467,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
if (!isset($tpl->compiled)) {
$tpl->compiled = $this->compiled;
if ($tpl->compiled->includes[$tpl->source->type . ':' . $tpl->source->name] > 1) {
$tpl->smarty->template_objects[$tpl->templateId] = $tpl;
$tpl->cacheTpl(true);
}
}
if ($this->smarty->debugging) {
@@ -587,6 +484,21 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
}
}
/**
* Cache resources for current template
*
* @param bool $cache_tpl_obj force caching
*/
public function cacheTpl($cache_tpl_obj)
{
if (!$this->source->handler->recompiled && (isset($this->smarty->template_objects[$this->parent->templateId]) ||
($cache_tpl_obj && $this->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_AUTOMATIC) ||
$this->smarty->resource_cache_mode & Smarty::RESOURCE_CACHE_ON)
) {
$this->smarty->->template_objects[$tpl->templateId] = $this;
}
}
/**
* Call template function
*

View File

@@ -74,6 +74,128 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
*/
public $cache_lifetime = 3600;
/**
* fetches a rendered Smarty template
*
* @param string $template the resource handle of the template file or template object
* @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)
{
$result = $this->_execute($template, $cache_id, $compile_id, $parent, 'fetch');
return $result === null ? ob_get_clean() : $result;
}
/**
* displays a Smarty template
*
* @param string $template the resource handle of the template file or template object
* @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
*/
public function display($template = null, $cache_id = null, $compile_id = null, $parent = null)
{
// display template
$this->_execute($template, $cache_id, $compile_id, $parent, 'display');
}
/**
* test if cache is valid
*
* @api Smarty::isCached()
* @link http://www.smarty.net/docs/en/api.is.cached.tpl
*
* @param null|string|\Smarty_Internal_Template $template the resource handle of the template file or template object
* @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
*
* @return boolean cache status
*/
public function isCached($template = null, $cache_id = null, $compile_id = null, $parent = null)
{
return $this->_execute($template, $cache_id, $compile_id, $parent, 'isCached');
}
/**
* fetches a rendered Smarty template
*
* @param string $template the resource handle of the template file or template object
* @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
*
* @return mixed
* @throws \Exception
* @throws \SmartyException
*/
private function _execute($template, $cache_id, $compile_id, $parent, $function)
{
/* @var Smarty $smarty */
$smarty = $this->_objType == 1 ? $this : $this->smarty;
if ($template === null) {
if ($this->_objType != 2) {
throw new SmartyException($function . '():Missing \'$template\' parameter');
} else {
$template = $this;
}
} elseif (is_object($template)) {
if (!isset($template->_objType) || $template->_objType != 2) {
throw new SmartyException($function . '():Template object expected');
}
} else {
// get template object
/* @var Smarty_Internal_Template $template */
$template = $smarty->createTemplate($template, $cache_id, $compile_id, $parent, false);
if ($this->_objType == 1) {
// set caching in template object
$template->caching = $this->caching;
}
}
// fetch template content
$level = ob_get_level();
try {
$_smarty_old_error_level = ($this->_objType == 1 &&
isset($smarty->error_reporting)) ? error_reporting($smarty->error_reporting) : null;
if ($function == 'isCached') {
if ($template->caching) {
// return cache status of template
if (!isset($template->cached)) {
$template->loadCached();
}
$result = $template->cached->isCached($template);
$template->smarty->_cache['isCached'][$template->templateId] = $template;
} else {
return false;
}
} else {
ob_start();
$result = $template->render(true, false, $function == 'display');
}
if (isset($_smarty_old_error_level)) {
error_reporting($_smarty_old_error_level);
}
return $result;
}
catch (Exception $e) {
while (ob_get_level() > $level) {
ob_end_clean();
}
throw $e;
}
}
/**
* Registers plugin to be used in templates
* NOTE: this method can be safely removed for dynamic loading
@@ -233,40 +355,6 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
return $this;
}
/**
* test if cache is valid
*
* @api Smarty::isCached()
* @link http://www.smarty.net/docs/en/api.is.cached.tpl
*
* @param string|\Smarty_Internal_Template $template the resource handle of the template file or template object
* @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
*
* @return boolean cache status
*/
public function isCached($template = null, $cache_id = null, $compile_id = null, $parent = null)
{
if ($template === null && $this instanceof $this->template_class) {
$template = $this;
} else {
if (!($template instanceof $this->template_class)) {
if ($parent === null) {
$parent = $this;
}
/* @var Smarty $smarty */
$smarty = isset($this->smarty) ? $this->smarty : $this;
$template = $smarty->createTemplate($template, $cache_id, $compile_id, $parent, false);
}
}
// return cache status of template
if (!isset($template->cached)) {
$template->loadCached();
}
return $template->cached->isCached($template);
}
/**
* @param boolean $caching
*/

View File

@@ -997,7 +997,7 @@ abstract class Smarty_Internal_TemplateCompilerBase
// If the template is not evaluated and we have a nocache section and or a nocache tag
if ($is_code && !empty($content)) {
// generate replacement code
if ((!($this->template->source->recompiled) || $this->forceNocache) && $this->template->caching &&
if ((!($this->template->source->handler->recompiled) || $this->forceNocache) && $this->template->caching &&
!$this->suppressNocacheProcessing && ($this->nocache || $this->tag_nocache)
) {
$this->template->compiled->has_nocache_code = true;

View File

@@ -42,6 +42,13 @@ abstract class Smarty_Resource
'eval' => 'smarty_internal_resource_eval.php',
'php' => 'smarty_internal_resource_php.php');
/**
* Flag if resource does implement populateCompiledFilepath() method
*
* @var bool
*/
public $hasCompiledHandler = false;
/**
* Name of the Class to compile this resource's contents with
*
@@ -139,19 +146,14 @@ abstract class Smarty_Resource
public static function load(Smarty $smarty, $type)
{
// try smarty's cache
if (isset($smarty->_resource_handlers[$type])) {
return $smarty->_resource_handlers[$type];
if (isset($smarty->_cache['resource_handlers'][$type])) {
return $smarty->_cache['resource_handlers'][$type];
}
// try registered resource
if (isset($smarty->registered_resources[$type])) {
if ($smarty->registered_resources[$type] instanceof Smarty_Resource) {
$smarty->_resource_handlers[$type] = $smarty->registered_resources[$type];
} else {
$smarty->_resource_handlers[$type] = new Smarty_Internal_Resource_Registered();
}
return $smarty->_resource_handlers[$type];
return $smarty->_cache['resource_handlers'][$type] = $smarty->registered_resources[$type] instanceof
Smarty_Resource ? $smarty->registered_resources[$type] : new Smarty_Internal_Resource_Registered();
}
// try sysplugins dir
@@ -160,14 +162,14 @@ abstract class Smarty_Resource
if (!class_exists($_resource_class, false)) {
require SMARTY_SYSPLUGINS_DIR . self::$sysplugins[$type];
}
return $smarty->_resource_handlers[$type] = new $_resource_class();
return $smarty->_cache['resource_handlers'][$type] = new $_resource_class();
}
// try plugins dir
$_resource_class = 'Smarty_Resource_' . ucfirst($type);
if ($smarty->loadPlugin($_resource_class)) {
if (class_exists($_resource_class, false)) {
return $smarty->_resource_handlers[$type] = new $_resource_class();
return $smarty->_cache['resource_handlers'][$type] = new $_resource_class();
} else {
$smarty->registerResource($type, array("smarty_resource_{$type}_source",
"smarty_resource_{$type}_timestamp",
@@ -185,7 +187,7 @@ abstract class Smarty_Resource
if (is_object($smarty->security_policy)) {
$smarty->security_policy->isTrustedStream($type);
}
return $smarty->_resource_handlers[$type] = new Smarty_Internal_Resource_Stream();
return $smarty->_cache['resource_handlers'][$type] = new Smarty_Internal_Resource_Stream();
}
// TODO: try default_(template|config)_handler
@@ -229,23 +231,23 @@ abstract class Smarty_Resource
/**
* modify template_resource according to resource handlers specifications
*
* @param Smarty_Internal_template $template Smarty instance
* @param string $template_resource template_resource to extract resource handler and name of
* @param \Smarty_Internal_Template|\Smarty $obj Smarty instance
* @param string $template_resource template_resource to extract resource handler and name of
*
* @return string unique resource name
*/
public static function getUniqueTemplateName($template, $template_resource)
public static function getUniqueTemplateName($obj, $template_resource)
{
$smarty = isset($template->smarty) ? $template->smarty : $template;
$smarty = $obj->_objType == 2 ? $obj->smarty : $obj;
list($name, $type) = self::parseResourceName($template_resource, $smarty->default_resource_type);
// TODO: optimize for Smarty's internal resource types
$resource = Smarty_Resource::load($smarty, $type);
// go relative to a given template?
$_file_is_dotted = $name[0] == '.' && ($name[1] == '.' || $name[1] == '/');
if ($template instanceof Smarty_Internal_Template && $_file_is_dotted &&
($template->source->type == 'file' || $template->parent->source->type == 'extends')
if ($obj->_objType == 2 && $_file_is_dotted &&
($obj->source->type == 'file' || $obj->parent->source->type == 'extends')
) {
$name = dirname($template->source->filepath) . DS . $name;
$name = dirname($obj->source->filepath) . DS . $name;
}
return $resource->buildUniqueResourceName($smarty, $name);
}

View File

@@ -23,6 +23,13 @@ abstract class Smarty_Resource_Recompiled extends Smarty_Resource
*/
public $recompiled = true;
/**
* Resource does implement populateCompiledFilepath() method
*
* @var bool
*/
public $hasCompiledHandler = true;
/**
* populate Compiled Object with compiled filepath
*

View File

@@ -23,6 +23,13 @@ abstract class Smarty_Resource_Uncompiled extends Smarty_Resource
*/
public $uncompiled = true;
/**
* Resource does implement populateCompiledFilepath() method
*
* @var bool
*/
public $hasCompiledHandler = true;
/**
* Render and output the template (without using the compiler)
*

View File

@@ -67,7 +67,7 @@ class Smarty_Template_Cached extends Smarty_Template_Resource_Base
/**
* Nocache hash codes of processed compiled templates
*
*
* @var array
*/
public $hashes = array();
@@ -106,6 +106,59 @@ class Smarty_Template_Cached extends Smarty_Template_Resource_Base
return $_template->cached;
}
/**
* Render cache template
*
* @param \Smarty_Internal_Template $_template
* @param bool $no_output_filter
*
* @throws \Exception
*/
public function render(Smarty_Internal_Template $_template, $no_output_filter = true)
{
if ($this->isCached($_template)) {
if ($_template->smarty->debugging) {
$_template->smarty->_debug->start_cache($_template);
}
if (!$this->processed) {
$this->process($_template);
}
$this->getRenderedTemplateCode($_template);
if ($_template->smarty->debugging) {
$_template->smarty->_debug->end_cache($_template);
}
return;
} elseif ($_template->source->handler->uncompiled) {
$_template->source->render($_template);
} else {
if (!isset($_template->compiled)) {
$_template->loadCompiled();
}
$_template->compiled->render($_template);
}
// write to cache when necessary
if ($_template->source->handler->recompiled) {
return;
}
if ($_template->smarty->debugging) {
$_template->smarty->_debug->start_cache($_template);
}
$_template->cached->updateCache($_template, $no_output_filter);
$compile_check = $_template->smarty->compile_check;
$_template->smarty->compile_check = false;
if (isset($this->parent) && $this->parent->_objType == 2) {
$_template->compiled->unifunc = $_template->parent->compiled->unifunc;
}
if (!$_template->cached->processed) {
$_template->cached->process($_template, true);
}
$_template->smarty->compile_check = $compile_check;
$this->getRenderedTemplateCode($_template);
if ($_template->smarty->debugging) {
$_template->smarty->_debug->end_cache($_template);
}
}
/**
* Check if cache is valid, lock cache if required
*
@@ -202,22 +255,6 @@ class Smarty_Template_Cached extends Smarty_Template_Resource_Base
}
}
/**
* Render cached template
*
* @param Smarty_Internal_Template $_template
*
* @return string
* @throws Exception
*/
public function render(Smarty_Internal_Template $_template)
{
if (!$this->processed) {
$this->process($_template);
}
$_template->getRenderedTemplateCode($this->unifunc);
}
/**
* Write this cache object to handler
*

View File

@@ -19,7 +19,6 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base
*/
public $nocache_hash = null;
/**
* create Compiled Object container
*/
@@ -48,7 +47,7 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base
}
}
$compiled = new Smarty_Template_Compiled();
if (method_exists($_template->source->handler, 'populateCompiledFilepath')) {
if ($_template->source->handler->hasCompiledHandler) {
$_template->source->handler->populateCompiledFilepath($compiled, $_template);
} else {
$compiled->populateCompiledFilepath($_template);
@@ -199,17 +198,25 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base
*/
public function render(Smarty_Internal_Template $_template)
{
if ($_template->smarty->debugging) {
$_template->smarty->_debug->start_render($_template);
}
if (!$this->processed) {
$this->process($_template);
}
if (isset($_template->cached)) {
$_template->cached->file_dependency = array_merge($_template->cached->file_dependency, $this->file_dependency);
}
$_template->getRenderedTemplateCode($this->unifunc);
$this->getRenderedTemplateCode($_template);
if ($_template->caching && $this->has_nocache_code) {
$_template->cached->hashes[$this->nocache_hash] = true;
}
if (isset($_template->parent) && $_template->parent->_objType == 2 && !empty($_template->tpl_function)) {
$_template->parent->tpl_function = array_merge($_template->parent->tpl_function, $_template->tpl_function);
}
if ($_template->smarty->debugging) {
$_template->smarty->_debug->end_render($_template);
}
}
/**

View File

@@ -2,7 +2,6 @@
/**
* Smarty Template Resource Base Object
* Meta Data Container for Template Resource Files
*
* @package Smarty
* @subpackage TemplateResources
@@ -101,64 +100,50 @@ abstract class Smarty_Template_Resource_Base
*/
abstract public function process(Smarty_Internal_Template $_template);
/**
* render template code
/**
* get rendered template content by calling compiled or cached template code
*
* @param Smarty_Internal_Template $_template
* @param string $unifunc function with template code
*
* @return string
* @throws Exception
* @throws \Exception
*/
public function render(Smarty_Internal_Template $_template)
public function getRenderedTemplateCode(Smarty_Internal_Template $_template, $unifunc = null)
{
if (!$this->processed) {
$this->process($_template);
}
return $_template->getRenderedTemplateCode($this->unifunc);
}
/**
* Write compiled code by handler
*
* @param Smarty_Internal_Template $_template template object
* @param string $code compiled code
*
* @return boolean success
*/
public function write(Smarty_Internal_Template $_template, $code)
{
if (!$_template->source->recompiled) {
$obj = new Smarty_Internal_Write_File();
if ($obj->writeFile($this->filepath, $code, $_template->smarty) === true) {
$this->timestamp = $this->exists = is_file($this->filepath);
if ($this->exists) {
$this->timestamp = filemtime($this->filepath);
return true;
}
$unifunc = isset($unifunc) ? $unifunc : $this->unifunc;
$level = ob_get_level();
try {
if (empty($unifunc) || !is_callable($unifunc)) {
throw new SmartyException("Invalid compiled template for '{$_template->template_resource}'");
}
return false;
} else {
$this->content = $code;
if (isset($_template->smarty->security_policy)) {
$_template->smarty->security_policy->startTemplate($_template);
}
array_unshift($_template->_capture_stack, array());
//
// render compiled or saved template code
//
$unifunc($_template);
// any unclosed {capture} tags ?
if (isset($_template->_capture_stack[0][0])) {
$_template->capture_error();
}
array_shift($_template->_capture_stack);
if (isset($_template->smarty->security_policy)) {
$_template->smarty->security_policy->exitTemplate();
}
return null;
}
$this->timestamp = time();
$this->exists = true;
return true;
}
/**
* Read compiled content from handler
*
* @param Smarty_Internal_Template $_template template object
*
* @return string content
*/
public function read(Smarty_Internal_Template $_template)
{
if (!$_template->source->recompiled) {
return file_get_contents($this->filepath);
catch (Exception $e) {
while (ob_get_level() > $level) {
ob_end_clean();
}
array_shift($_template->_capture_stack);
if (isset($_template->smarty->security_policy)) {
$_template->smarty->security_policy->exitTemplate();
}
throw $e;
}
return isset($this->content) ? $this->content : false;
}
/**

View File

@@ -251,6 +251,27 @@ class Smarty_Template_Source
$this->handler->renderUncompiled($_template->source, $_template);
}
/**
* Render uncompiled source
*
* @param \Smarty_Internal_Template $_template
*/
public function render(Smarty_Internal_Template $_template)
{
if ($_template->source->handler->uncompiled) {
if ($_template->smarty->debugging) {
$_template->smarty->_debug->start_render($_template);
}
$this->handler->renderUncompiled($_template->source, $_template);
if (isset($_template->parent) && $_template->parent->_objType == 2 && !empty($_template->tpl_function)) {
$_template->parent->tpl_function = array_merge($_template->parent->tpl_function, $_template->tpl_function);
}
if ($_template->smarty->debugging) {
$_template->smarty->_debug->end_render($_template);
}
}
}
/**
* Get source time stamp
*