mirror of
https://github.com/smarty-php/smarty.git
synced 2025-08-05 02:44:27 +02:00
restructure template processing
Code was moved into classes it better belongs to. This does reduce also Smarty's memory footprint
This commit is contained in:
@@ -1,5 +1,8 @@
|
|||||||
===== 3.1.22-dev ===== (xx.xx.2014)
|
===== 3.1.22-dev ===== (xx.xx.2015)
|
||||||
31.12.22014
|
|
||||||
|
- optimization restructure template processing by moving code into classes it better belongs to
|
||||||
|
|
||||||
|
31.12.2014
|
||||||
- bugfix use function_exists('mb_get_info') for setting Smarty::$_MBSTRING.
|
- bugfix use function_exists('mb_get_info') for setting Smarty::$_MBSTRING.
|
||||||
Function mb_split could be overloaded depending on php.ini mbstring.func_overload
|
Function mb_split could be overloaded depending on php.ini mbstring.func_overload
|
||||||
|
|
||||||
|
@@ -75,18 +75,24 @@ if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) {
|
|||||||
* If we fail we must load Smarty's autoloader.
|
* If we fail we must load Smarty's autoloader.
|
||||||
* Otherwise we may have a global autoloader like Composer
|
* Otherwise we may have a global autoloader like Composer
|
||||||
*/
|
*/
|
||||||
if (!class_exists('Smarty_Internal_Data', true)) {
|
if (!class_exists('Smarty_Autoloader', false)) {
|
||||||
require 'Autoloader.php';
|
if (!class_exists('Smarty_Internal_Data', true)) {
|
||||||
Smarty_Autoloader::registerBC();
|
require 'Autoloader.php';
|
||||||
require SMARTY_SYSPLUGINS_DIR . 'smarty_internal_data.php';
|
Smarty_Autoloader::registerBC();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Load always needed external class files
|
* Load always needed external class files
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if (!class_exists('Smarty_Internal_Data', false)) {
|
||||||
|
require SMARTY_SYSPLUGINS_DIR . 'smarty_internal_data.php';
|
||||||
|
}
|
||||||
require SMARTY_SYSPLUGINS_DIR . 'smarty_internal_templatebase.php';
|
require SMARTY_SYSPLUGINS_DIR . 'smarty_internal_templatebase.php';
|
||||||
require SMARTY_SYSPLUGINS_DIR . 'smarty_internal_template.php';
|
require SMARTY_SYSPLUGINS_DIR . 'smarty_internal_template.php';
|
||||||
require SMARTY_SYSPLUGINS_DIR . 'smarty_resource.php';
|
require SMARTY_SYSPLUGINS_DIR . 'smarty_resource.php';
|
||||||
|
require SMARTY_SYSPLUGINS_DIR . 'smarty_template_source.php';
|
||||||
require SMARTY_SYSPLUGINS_DIR . 'smarty_internal_resource_file.php';
|
require SMARTY_SYSPLUGINS_DIR . 'smarty_internal_resource_file.php';
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -632,8 +638,6 @@ class Smarty extends Smarty_Internal_TemplateBase
|
|||||||
*/
|
*/
|
||||||
public $_parserdebug = false;
|
public $_parserdebug = false;
|
||||||
|
|
||||||
/**#@-*/
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Cache of is_file results of loadPlugin()
|
* Cache of is_file results of loadPlugin()
|
||||||
*
|
*
|
||||||
@@ -677,70 +681,49 @@ class Smarty extends Smarty_Internal_TemplateBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Class destructor
|
* fetches a rendered Smarty template
|
||||||
*/
|
|
||||||
public function __destruct()
|
|
||||||
{
|
|
||||||
// intentionally left blank
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <<magic>> set selfpointer on cloned object
|
|
||||||
*/
|
|
||||||
public function __clone()
|
|
||||||
{
|
|
||||||
$this->smarty = $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* <<magic>> Generic getter.
|
|
||||||
* Calls the appropriate getter function.
|
|
||||||
* Issues an E_USER_NOTICE if no valid getter is found.
|
|
||||||
*
|
*
|
||||||
* @param string $name property name
|
* @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
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @throws Exception
|
||||||
|
* @throws SmartyException
|
||||||
|
* @return string rendered template output
|
||||||
*/
|
*/
|
||||||
public function __get($name)
|
public function fetch($template = null, $cache_id = null, $compile_id = null, $parent = null, $display = false, $merge_tpl_vars = true, $no_output_filter = false)
|
||||||
{
|
{
|
||||||
$allowed = array(
|
if ($cache_id !== null && is_object($cache_id)) {
|
||||||
'template_dir' => 'getTemplateDir',
|
$parent = $cache_id;
|
||||||
'config_dir' => 'getConfigDir',
|
$cache_id = null;
|
||||||
'plugins_dir' => 'getPluginsDir',
|
|
||||||
'compile_dir' => 'getCompileDir',
|
|
||||||
'cache_dir' => 'getCacheDir',
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isset($allowed[$name])) {
|
|
||||||
return $this->{$allowed[$name]}();
|
|
||||||
} else {
|
|
||||||
trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
|
|
||||||
}
|
}
|
||||||
|
if ($parent === null) {
|
||||||
|
$parent = $this;
|
||||||
|
}
|
||||||
|
// get template object
|
||||||
|
$_template = is_object($template) ? $template : $this->smarty->createTemplate($template, $cache_id, $compile_id, $parent, false);
|
||||||
|
// set caching in template object
|
||||||
|
$_template->caching = $this->caching;
|
||||||
|
// fetch template content
|
||||||
|
return $_template->render(true, false, $display);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* <<magic>> Generic setter.
|
* displays a Smarty template
|
||||||
* Calls the appropriate setter function.
|
|
||||||
* Issues an E_USER_NOTICE if no valid setter is found.
|
|
||||||
*
|
*
|
||||||
* @param string $name property name
|
* @param string $template the resource handle of the template file or template object
|
||||||
* @param mixed $value parameter passed to setter
|
* @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 __set($name, $value)
|
public function display($template = null, $cache_id = null, $compile_id = null, $parent = null)
|
||||||
{
|
{
|
||||||
$allowed = array(
|
// display template
|
||||||
'template_dir' => 'setTemplateDir',
|
$this->fetch($template, $cache_id, $compile_id, $parent, true);
|
||||||
'config_dir' => 'setConfigDir',
|
|
||||||
'plugins_dir' => 'setPluginsDir',
|
|
||||||
'compile_dir' => 'setCompileDir',
|
|
||||||
'cache_dir' => 'setCacheDir',
|
|
||||||
);
|
|
||||||
|
|
||||||
if (isset($allowed[$name])) {
|
|
||||||
$this->{$allowed[$name]}($value);
|
|
||||||
} else {
|
|
||||||
trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -880,9 +863,7 @@ class Smarty extends Smarty_Internal_TemplateBase
|
|||||||
foreach ((array) $template_dir as $k => $v) {
|
foreach ((array) $template_dir as $k => $v) {
|
||||||
$this->template_dir[$k] = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS;
|
$this->template_dir[$k] = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir);
|
$this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -922,7 +903,6 @@ class Smarty extends Smarty_Internal_TemplateBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
$this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir);
|
$this->joined_template_dir = join(DIRECTORY_SEPARATOR, $this->template_dir);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -938,7 +918,6 @@ class Smarty extends Smarty_Internal_TemplateBase
|
|||||||
if ($index !== null) {
|
if ($index !== null) {
|
||||||
return isset($this->template_dir[$index]) ? $this->template_dir[$index] : null;
|
return isset($this->template_dir[$index]) ? $this->template_dir[$index] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (array) $this->template_dir;
|
return (array) $this->template_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -955,9 +934,7 @@ class Smarty extends Smarty_Internal_TemplateBase
|
|||||||
foreach ((array) $config_dir as $k => $v) {
|
foreach ((array) $config_dir as $k => $v) {
|
||||||
$this->config_dir[$k] = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS;
|
$this->config_dir[$k] = preg_replace('#(\w+)(/|\\\\){1,}#', '$1$2', rtrim($v, '/\\')) . DS;
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir);
|
$this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -997,7 +974,6 @@ class Smarty extends Smarty_Internal_TemplateBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
$this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir);
|
$this->joined_config_dir = join(DIRECTORY_SEPARATOR, $this->config_dir);
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1013,7 +989,6 @@ class Smarty extends Smarty_Internal_TemplateBase
|
|||||||
if ($index !== null) {
|
if ($index !== null) {
|
||||||
return isset($this->config_dir[$index]) ? $this->config_dir[$index] : null;
|
return isset($this->config_dir[$index]) ? $this->config_dir[$index] : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (array) $this->config_dir;
|
return (array) $this->config_dir;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1089,7 +1064,6 @@ class Smarty extends Smarty_Internal_TemplateBase
|
|||||||
if (!isset(Smarty::$_muted_directories[$this->compile_dir])) {
|
if (!isset(Smarty::$_muted_directories[$this->compile_dir])) {
|
||||||
Smarty::$_muted_directories[$this->compile_dir] = null;
|
Smarty::$_muted_directories[$this->compile_dir] = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this;
|
return $this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1601,6 +1575,73 @@ class Smarty extends Smarty_Internal_TemplateBase
|
|||||||
$this->compile_locking = $compile_locking;
|
$this->compile_locking = $compile_locking;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class destructor
|
||||||
|
*/
|
||||||
|
public function __destruct()
|
||||||
|
{
|
||||||
|
// intentionally left blank
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <<magic>> set selfpointer on cloned object
|
||||||
|
*/
|
||||||
|
public function __clone()
|
||||||
|
{
|
||||||
|
$this->smarty = $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <<magic>> Generic getter.
|
||||||
|
* Calls the appropriate getter function.
|
||||||
|
* Issues an E_USER_NOTICE if no valid getter is found.
|
||||||
|
*
|
||||||
|
* @param string $name property name
|
||||||
|
*
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
public function __get($name)
|
||||||
|
{
|
||||||
|
$allowed = array(
|
||||||
|
'template_dir' => 'getTemplateDir',
|
||||||
|
'config_dir' => 'getConfigDir',
|
||||||
|
'plugins_dir' => 'getPluginsDir',
|
||||||
|
'compile_dir' => 'getCompileDir',
|
||||||
|
'cache_dir' => 'getCacheDir',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isset($allowed[$name])) {
|
||||||
|
return $this->{$allowed[$name]}();
|
||||||
|
} else {
|
||||||
|
trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* <<magic>> Generic setter.
|
||||||
|
* Calls the appropriate setter function.
|
||||||
|
* Issues an E_USER_NOTICE if no valid setter is found.
|
||||||
|
*
|
||||||
|
* @param string $name property name
|
||||||
|
* @param mixed $value parameter passed to setter
|
||||||
|
*/
|
||||||
|
public function __set($name, $value)
|
||||||
|
{
|
||||||
|
$allowed = array(
|
||||||
|
'template_dir' => 'setTemplateDir',
|
||||||
|
'config_dir' => 'setConfigDir',
|
||||||
|
'plugins_dir' => 'setPluginsDir',
|
||||||
|
'compile_dir' => 'setCompileDir',
|
||||||
|
'cache_dir' => 'setCacheDir',
|
||||||
|
);
|
||||||
|
|
||||||
|
if (isset($allowed[$name])) {
|
||||||
|
$this->{$allowed[$name]}($value);
|
||||||
|
} else {
|
||||||
|
trigger_error('Undefined property: ' . get_class($this) . '::$' . $name, E_USER_NOTICE);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Error Handler to mute expected messages
|
* Error Handler to mute expected messages
|
||||||
*
|
*
|
||||||
|
@@ -122,6 +122,231 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* fetches rendered template
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
* @throws SmartyException
|
||||||
|
* @return string rendered template output
|
||||||
|
*/
|
||||||
|
public function fetch()
|
||||||
|
{
|
||||||
|
return $this->render(true, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* displays a Smarty template
|
||||||
|
|
||||||
|
*/
|
||||||
|
public function display()
|
||||||
|
{
|
||||||
|
$this->render(true, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* render template
|
||||||
|
*
|
||||||
|
* @param bool $merge_tpl_vars if true parent template variables merged in to local scope
|
||||||
|
* @param bool $no_output_filter if true do not run output filter
|
||||||
|
* @param bool $display true: display, false: fetch
|
||||||
|
*
|
||||||
|
* @throws Exception
|
||||||
|
* @throws SmartyException
|
||||||
|
* @return string rendered template output
|
||||||
|
*/
|
||||||
|
public function render($merge_tpl_vars = false, $no_output_filter = true, $display = false)
|
||||||
|
{
|
||||||
|
if ($this->smarty->debugging) {
|
||||||
|
Smarty_Internal_Debug::start_template($this);
|
||||||
|
}
|
||||||
|
// 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;
|
||||||
|
}
|
||||||
|
// dummy local smarty variable
|
||||||
|
if (!isset($this->tpl_vars['smarty'])) {
|
||||||
|
$this->tpl_vars['smarty'] = new Smarty_Variable;
|
||||||
|
}
|
||||||
|
if (isset($this->smarty->error_reporting)) {
|
||||||
|
$_smarty_old_error_level = error_reporting($this->smarty->error_reporting);
|
||||||
|
}
|
||||||
|
// check URL debugging control
|
||||||
|
if (!$this->smarty->debugging && $this->smarty->debugging_ctrl == 'URL') {
|
||||||
|
Smarty_Internal_Debug::debugUrl($this);
|
||||||
|
}
|
||||||
|
// checks if template exists
|
||||||
|
if (!$this->source->exists) {
|
||||||
|
if ($this->parent instanceof Smarty_Internal_Template) {
|
||||||
|
$parent_resource = " in '{$this->parent->template_resource}'";
|
||||||
|
} else {
|
||||||
|
$parent_resource = '';
|
||||||
|
}
|
||||||
|
throw new SmartyException("Unable to load template {$this->source->type} '{$this->source->name}'{$parent_resource}");
|
||||||
|
}
|
||||||
|
// disable caching for evaluated code
|
||||||
|
if ($this->source->recompiled) {
|
||||||
|
$this->caching = false;
|
||||||
|
}
|
||||||
|
// read from cache or render
|
||||||
|
if (!($this->caching == Smarty::CACHING_LIFETIME_CURRENT || $this->caching == Smarty::CACHING_LIFETIME_SAVED) || !$this->cached->valid) {
|
||||||
|
// render template (not loaded and not in cache)
|
||||||
|
if ($this->smarty->debugging) {
|
||||||
|
Smarty_Internal_Debug::start_render($this);
|
||||||
|
}
|
||||||
|
if (!$this->source->uncompiled) {
|
||||||
|
// render compiled code
|
||||||
|
$content = $this->compiled->render($this);
|
||||||
|
} else {
|
||||||
|
$content = $this->source->renderUncompiled($this);
|
||||||
|
}
|
||||||
|
if (!$this->source->recompiled && empty($this->properties['file_dependency'][$this->source->uid])) {
|
||||||
|
$this->properties['file_dependency'][$this->source->uid] = array($this->source->filepath, $this->source->timestamp, $this->source->type);
|
||||||
|
}
|
||||||
|
if ($this->parent instanceof Smarty_Internal_Template) {
|
||||||
|
$this->parent->properties['file_dependency'] = array_merge($this->parent->properties['file_dependency'], $this->properties['file_dependency']);
|
||||||
|
$this->parent->properties['tpl_function'] = array_merge($this->parent->properties['tpl_function'], $this->properties['tpl_function']);
|
||||||
|
foreach ($this->required_plugins as $code => $tmp1) {
|
||||||
|
foreach ($tmp1 as $name => $tmp) {
|
||||||
|
foreach ($tmp as $type => $data) {
|
||||||
|
$this->parent->required_plugins[$code][$name][$type] = $data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($this->smarty->debugging) {
|
||||||
|
Smarty_Internal_Debug::end_render($this);
|
||||||
|
}
|
||||||
|
// write to cache when necessary
|
||||||
|
if (!$this->source->recompiled && ($this->caching == Smarty::CACHING_LIFETIME_SAVED || $this->caching == Smarty::CACHING_LIFETIME_CURRENT)) {
|
||||||
|
if ($this->smarty->debugging) {
|
||||||
|
Smarty_Internal_Debug::start_cache($this);
|
||||||
|
}
|
||||||
|
$this->cached->updateCache($this, $content, $no_output_filter);
|
||||||
|
$compile_check = $this->smarty->compile_check;
|
||||||
|
$this->smarty->compile_check = false;
|
||||||
|
$content = $this->cached->render($this);
|
||||||
|
$this->smarty->compile_check = $compile_check;
|
||||||
|
if ($this->smarty->debugging) {
|
||||||
|
Smarty_Internal_Debug::end_cache($this);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if (!empty($this->properties['nocache_hash']) && !empty($this->parent->properties['nocache_hash'])) {
|
||||||
|
// replace nocache_hash
|
||||||
|
$content = str_replace("{$this->properties['nocache_hash']}", $this->parent->properties['nocache_hash'], $content);
|
||||||
|
$this->parent->has_nocache_code = $this->parent->has_nocache_code || $this->has_nocache_code;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
if ($this->smarty->debugging) {
|
||||||
|
Smarty_Internal_Debug::start_cache($this);
|
||||||
|
}
|
||||||
|
$content = $this->cached->render($this);
|
||||||
|
if ($this->smarty->debugging) {
|
||||||
|
Smarty_Internal_Debug::end_cache($this);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ((!$this->caching || $this->has_nocache_code || $this->source->recompiled) && !$no_output_filter && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) {
|
||||||
|
$content = Smarty_Internal_Filter_Handler::runFilter('output', $content, $this);
|
||||||
|
}
|
||||||
|
if (isset($this->error_reporting)) {
|
||||||
|
error_reporting($_smarty_old_error_level);
|
||||||
|
}
|
||||||
|
// display or fetch
|
||||||
|
if ($display) {
|
||||||
|
if ($this->caching && $this->smarty->cache_modified_check) {
|
||||||
|
$this->cached->cacheModifiedCheck($this, $content);
|
||||||
|
} else {
|
||||||
|
echo $content;
|
||||||
|
}
|
||||||
|
if ($this->smarty->debugging) {
|
||||||
|
Smarty_Internal_Debug::end_template($this);
|
||||||
|
}
|
||||||
|
// debug output
|
||||||
|
if ($this->smarty->debugging) {
|
||||||
|
Smarty_Internal_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) {
|
||||||
|
Smarty_Internal_Debug::end_template($this);
|
||||||
|
}
|
||||||
|
// return fetched content
|
||||||
|
return $content;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get rendered template content by calling compiled or cached template code
|
||||||
|
*
|
||||||
|
* @return string
|
||||||
|
* @throws Exception
|
||||||
|
*/
|
||||||
|
public function getRenderedTemplateCode()
|
||||||
|
{
|
||||||
|
try {
|
||||||
|
ob_start();
|
||||||
|
if (empty($this->properties['unifunc']) || !is_callable($this->properties['unifunc'])) {
|
||||||
|
throw new SmartyException("Invalid compiled template for '{$this->template_resource}'");
|
||||||
|
}
|
||||||
|
if (isset($this->smarty->security_policy)) {
|
||||||
|
$this->smarty->security_policy->startTemplate($this);
|
||||||
|
}
|
||||||
|
array_unshift($this->_capture_stack, array());
|
||||||
|
//
|
||||||
|
// render compiled or saved template code
|
||||||
|
//
|
||||||
|
$this->properties['unifunc']($this);
|
||||||
|
// any unclosed {capture} tags ?
|
||||||
|
if (isset($this->_capture_stack[0][0])) {
|
||||||
|
$this->capture_error();
|
||||||
|
}
|
||||||
|
array_shift($this->_capture_stack);
|
||||||
|
if (isset($this->smarty->security_policy)) {
|
||||||
|
$this->smarty->security_policy->exitTemplate($this);
|
||||||
|
}
|
||||||
|
return ob_get_clean();
|
||||||
|
}
|
||||||
|
catch (Exception $e) {
|
||||||
|
ob_get_clean();
|
||||||
|
throw $e;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns if the current template must be compiled by the Smarty compiler
|
* Returns if the current template must be compiled by the Smarty compiler
|
||||||
* It does compare the timestamps of template source and the compiled templates and checks the force compile configuration
|
* It does compare the timestamps of template source and the compiled templates and checks the force compile configuration
|
||||||
@@ -153,43 +378,11 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
*/
|
*/
|
||||||
public function compileTemplateSource()
|
public function compileTemplateSource()
|
||||||
{
|
{
|
||||||
if (!$this->source->recompiled) {
|
return $this->compiled->compileTemplateSource($this);
|
||||||
$this->properties['file_dependency'] = array();
|
|
||||||
}
|
|
||||||
// compile locking
|
|
||||||
if ($this->smarty->compile_locking && !$this->source->recompiled) {
|
|
||||||
if ($saved_timestamp = $this->compiled->timestamp) {
|
|
||||||
touch($this->compiled->filepath);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// call compiler
|
|
||||||
try {
|
|
||||||
$code = $this->compiler->compileTemplate($this);
|
|
||||||
}
|
|
||||||
catch (Exception $e) {
|
|
||||||
// restore old timestamp in case of error
|
|
||||||
if ($this->smarty->compile_locking && !$this->source->recompiled && $saved_timestamp) {
|
|
||||||
touch($this->compiled->filepath, $saved_timestamp);
|
|
||||||
}
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
// compiling succeded
|
|
||||||
if (!$this->source->recompiled && $this->compiler->write_compiled_code) {
|
|
||||||
// write compiled template
|
|
||||||
$_filepath = $this->compiled->filepath;
|
|
||||||
if ($_filepath === false) {
|
|
||||||
throw new SmartyException('getCompiledFilepath() did not return a destination to save the compiled template to');
|
|
||||||
}
|
|
||||||
Smarty_Internal_Write_File::writeFile($_filepath, $code, $this->smarty);
|
|
||||||
$this->compiled->exists = true;
|
|
||||||
$this->compiled->isCompiled = true;
|
|
||||||
}
|
|
||||||
// release compiler object to free memory
|
|
||||||
unset($this->compiler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes the cached template output
|
* Writes the content to cache resource
|
||||||
*
|
*
|
||||||
* @param string $content
|
* @param string $content
|
||||||
*
|
*
|
||||||
@@ -197,15 +390,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
*/
|
*/
|
||||||
public function writeCachedContent($content)
|
public function writeCachedContent($content)
|
||||||
{
|
{
|
||||||
if ($this->source->recompiled || !($this->caching == Smarty::CACHING_LIFETIME_CURRENT || $this->caching == Smarty::CACHING_LIFETIME_SAVED)) {
|
return $this->cached->writeCachedContent($this, $content);
|
||||||
// don't write cache file
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
$this->cached->timestamp = time();
|
|
||||||
$this->properties['cache_lifetime'] = $this->cache_lifetime;
|
|
||||||
$this->properties['unifunc'] = 'content_' . str_replace(array('.', ','), '_', uniqid('', true));
|
|
||||||
$content = $this->createTemplateCodeFrame($content, true);
|
|
||||||
return $this->cached->write($this, $content);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -223,16 +408,27 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
*/
|
*/
|
||||||
public function getSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope)
|
public function getSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope)
|
||||||
{
|
{
|
||||||
// already in template cache?
|
$tpl = $this->setupSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope);
|
||||||
if ($this->smarty->allow_ambiguous_resources) {
|
return $tpl->render();
|
||||||
$_templateId = Smarty_Resource::getUniqueTemplateName($this, $template) . $cache_id . $compile_id;
|
}
|
||||||
} else {
|
|
||||||
$_templateId = $this->smarty->joined_template_dir . '#' . $template . $cache_id . $compile_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_templateId[150])) {
|
/**
|
||||||
$_templateId = sha1($_templateId);
|
* 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 array $data passed parameter template variables
|
||||||
|
* @param int $parent_scope scope in which {include} should execute
|
||||||
|
*
|
||||||
|
* @returns object template object
|
||||||
|
*/
|
||||||
|
public function setupSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope)
|
||||||
|
{
|
||||||
|
$_templateId = $this->getTemplateId($template, $cache_id, $compile_id);
|
||||||
|
// already in template cache?
|
||||||
if (isset($this->smarty->template_objects[$_templateId])) {
|
if (isset($this->smarty->template_objects[$_templateId])) {
|
||||||
// clone cached template object because of possible recursive call
|
// clone cached template object because of possible recursive call
|
||||||
$tpl = clone $this->smarty->template_objects[$_templateId];
|
$tpl = clone $this->smarty->template_objects[$_templateId];
|
||||||
@@ -244,6 +440,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
$tpl->cache_lifetime = $cache_lifetime;
|
$tpl->cache_lifetime = $cache_lifetime;
|
||||||
} else {
|
} else {
|
||||||
$tpl = new $this->smarty->template_class($template, $this->smarty, $this, $cache_id, $compile_id, $caching, $cache_lifetime);
|
$tpl = new $this->smarty->template_class($template, $this->smarty, $this, $cache_id, $compile_id, $caching, $cache_lifetime);
|
||||||
|
$tpl->templateId = $_templateId;
|
||||||
}
|
}
|
||||||
// get variables from calling scope
|
// get variables from calling scope
|
||||||
if ($parent_scope == Smarty::SCOPE_LOCAL) {
|
if ($parent_scope == Smarty::SCOPE_LOCAL) {
|
||||||
@@ -265,49 +462,6 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
$tpl->tpl_vars[$_key] = new Smarty_variable($_val);
|
$tpl->tpl_vars[$_key] = new Smarty_variable($_val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return $tpl->fetch(null, null, null, null, false, false, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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
|
|
||||||
*
|
|
||||||
* @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;
|
|
||||||
$tpl->tpl_vars['smarty'] = clone $this->tpl_vars['smarty'];
|
|
||||||
} 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;
|
|
||||||
}
|
|
||||||
$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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return $tpl;
|
return $tpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -319,7 +473,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
* @param mixed $compile_id compile 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 $caching cache mode
|
||||||
* @param integer $cache_lifetime life time of cache data
|
* @param integer $cache_lifetime life time of cache data
|
||||||
* @param $data
|
* @param array $data passed parameter template variables
|
||||||
* @param int $parent_scope scope in which {include} should execute
|
* @param int $parent_scope scope in which {include} should execute
|
||||||
* @param string $hash nocache hash code
|
* @param string $hash nocache hash code
|
||||||
* @param string $content_func name of content function
|
* @param string $content_func name of content function
|
||||||
@@ -328,17 +482,18 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
*/
|
*/
|
||||||
public function getInlineSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope, $hash, $content_func)
|
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);
|
$tpl = $this->setupSubTemplate($template, $cache_id, $compile_id, $caching, $cache_lifetime, $data, $parent_scope);
|
||||||
if (isset($this->smarty->security_policy)) {
|
$tpl->properties['nocache_hash'] = $hash;
|
||||||
$this->smarty->security_policy->startTemplate($tpl);
|
$tpl->properties['tpl_function'] = $this->properties['tpl_function'];
|
||||||
|
if (!isset($this->smarty->template_objects[$tpl->templateId])) {
|
||||||
|
$this->smarty->template_objects[$tpl->templateId] = $tpl;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->smarty->debugging) {
|
if ($this->smarty->debugging) {
|
||||||
Smarty_Internal_Debug::start_template($tpl);
|
Smarty_Internal_Debug::start_template($tpl);
|
||||||
Smarty_Internal_Debug::start_render($tpl);
|
Smarty_Internal_Debug::start_render($tpl);
|
||||||
}
|
}
|
||||||
ob_start();
|
$tpl->properties['unifunc'] = $content_func;
|
||||||
$content_func($tpl);
|
$output = $tpl->getRenderedTemplateCode();
|
||||||
if ($this->smarty->debugging) {
|
if ($this->smarty->debugging) {
|
||||||
Smarty_Internal_Debug::end_template($tpl);
|
Smarty_Internal_Debug::end_template($tpl);
|
||||||
Smarty_Internal_Debug::end_render($tpl);
|
Smarty_Internal_Debug::end_render($tpl);
|
||||||
@@ -346,10 +501,8 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
if (!empty($tpl->properties['file_dependency'])) {
|
if (!empty($tpl->properties['file_dependency'])) {
|
||||||
$this->properties['file_dependency'] = array_merge($this->properties['file_dependency'], $tpl->properties['file_dependency']);
|
$this->properties['file_dependency'] = array_merge($this->properties['file_dependency'], $tpl->properties['file_dependency']);
|
||||||
}
|
}
|
||||||
if (isset($this->smarty->security_policy)) {
|
$this->properties['tpl_function'] = $tpl->properties['tpl_function'];
|
||||||
$this->smarty->security_policy->exitTemplate($tpl);
|
return str_replace($tpl->properties['nocache_hash'], $this->properties['nocache_hash'], $output);
|
||||||
}
|
|
||||||
return str_replace($tpl->properties['nocache_hash'], $this->properties['nocache_hash'], ob_get_clean());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -406,7 +559,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
if (Smarty::SMARTY_VERSION != $properties['version']) {
|
if (Smarty::SMARTY_VERSION != $properties['version']) {
|
||||||
// new version must rebuild
|
// new version must rebuild
|
||||||
$is_valid = false;
|
$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($properties['file_dependency'])) {
|
} elseif ((!$cache && $this->smarty->compile_check || $cache && ($this->smarty->compile_check === true || $this->smarty->compile_check === Smarty::COMPILECHECK_ON)) && !empty($properties['file_dependency'])) {
|
||||||
// check file dependencies at compiled code
|
// check file dependencies at compiled code
|
||||||
foreach ($properties['file_dependency'] as $_file_to_check) {
|
foreach ($properties['file_dependency'] as $_file_to_check) {
|
||||||
if ($_file_to_check[2] == 'file' || $_file_to_check[2] == 'php') {
|
if ($_file_to_check[2] == 'file' || $_file_to_check[2] == 'php') {
|
||||||
@@ -441,10 +594,6 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
} else {
|
} else {
|
||||||
$this->mustCompile = !$is_valid;
|
$this->mustCompile = !$is_valid;
|
||||||
}
|
}
|
||||||
// store data in reusable Smarty_Template_Compiled
|
|
||||||
if (!$cache) {
|
|
||||||
$this->compiled->_properties = $properties;
|
|
||||||
}
|
|
||||||
if ($is_valid) {
|
if ($is_valid) {
|
||||||
$this->has_nocache_code = $properties['has_nocache_code'];
|
$this->has_nocache_code = $properties['has_nocache_code'];
|
||||||
// $this->properties['nocache_hash'] = $properties['nocache_hash'];
|
// $this->properties['nocache_hash'] = $properties['nocache_hash'];
|
||||||
@@ -460,7 +609,6 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
}
|
}
|
||||||
$this->properties['version'] = $properties['version'];
|
$this->properties['version'] = $properties['version'];
|
||||||
$this->properties['unifunc'] = $properties['unifunc'];
|
$this->properties['unifunc'] = $properties['unifunc'];
|
||||||
$this->properties['type'] = $properties['type'];
|
|
||||||
}
|
}
|
||||||
return $is_valid;
|
return $is_valid;
|
||||||
}
|
}
|
||||||
@@ -516,7 +664,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
/**
|
/**
|
||||||
* Get parent or root of template parent chain
|
* Get parent or root of template parent chain
|
||||||
*
|
*
|
||||||
* @param int $scope pqrent or root scope
|
* @param int $scope parent or root scope
|
||||||
*
|
*
|
||||||
* @return mixed object
|
* @return mixed object
|
||||||
*/
|
*/
|
||||||
@@ -537,7 +685,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* [util function] counts an array, arrayaccess/traversable or PDOStatement object
|
* [util function] counts an array, arrayAccess/traversable or PDOStatement object
|
||||||
*
|
*
|
||||||
* @param mixed $value
|
* @param mixed $value
|
||||||
*
|
*
|
||||||
@@ -627,43 +775,25 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase
|
|||||||
*
|
*
|
||||||
* @param string $property_name property name
|
* @param string $property_name property name
|
||||||
*
|
*
|
||||||
|
* @return mixed|Smarty_Template_Cached
|
||||||
* @throws SmartyException
|
* @throws SmartyException
|
||||||
*/
|
*/
|
||||||
public function __get($property_name)
|
public function __get($property_name)
|
||||||
{
|
{
|
||||||
switch ($property_name) {
|
switch ($property_name) {
|
||||||
case 'source':
|
case 'source':
|
||||||
if (strlen($this->template_resource) == 0) {
|
$this->source = Smarty_Template_Source::load($this);
|
||||||
throw new SmartyException('Missing template name');
|
if ($this->smarty->template_resource_caching && !$this->source->recompiled && isset($this->templateId)) {
|
||||||
|
$this->smarty->template_objects[$this->templateId] = $this;
|
||||||
}
|
}
|
||||||
$this->source = Smarty_Resource::source($this);
|
|
||||||
// cache template object under a unique ID
|
|
||||||
// do not cache eval resources
|
|
||||||
if ($this->source->type != 'eval') {
|
|
||||||
if ($this->smarty->allow_ambiguous_resources) {
|
|
||||||
$_templateId = $this->source->unique_resource . $this->cache_id . $this->compile_id;
|
|
||||||
} else {
|
|
||||||
$_templateId = $this->smarty->joined_template_dir . '#' . $this->template_resource . $this->cache_id . $this->compile_id;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($_templateId[150])) {
|
|
||||||
$_templateId = sha1($_templateId);
|
|
||||||
}
|
|
||||||
$this->smarty->template_objects[$_templateId] = $this;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $this->source;
|
return $this->source;
|
||||||
|
|
||||||
case 'compiled':
|
case 'compiled':
|
||||||
$this->compiled = $this->source->getCompiled($this);
|
$this->compiled = Smarty_Template_Compiled::load($this);
|
||||||
|
|
||||||
return $this->compiled;
|
return $this->compiled;
|
||||||
|
|
||||||
case 'cached':
|
case 'cached':
|
||||||
if (!class_exists('Smarty_Template_Cached')) {
|
$this->cached = Smarty_Template_Cached::load($this);
|
||||||
include SMARTY_SYSPLUGINS_DIR . 'smarty_cacheresource.php';
|
|
||||||
}
|
|
||||||
$this->cached = new Smarty_Template_Cached($this);
|
|
||||||
|
|
||||||
return $this->cached;
|
return $this->cached;
|
||||||
|
|
||||||
|
@@ -49,383 +49,6 @@ abstract class Smarty_Internal_TemplateBase extends Smarty_Internal_Data
|
|||||||
*/
|
*/
|
||||||
public $cache_lifetime = 3600;
|
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 true: display, false: fetch
|
|
||||||
* @param bool $merge_tpl_vars if true parent template variables merged in to local scope
|
|
||||||
* @param bool $no_output_filter if true do not run output filter
|
|
||||||
*
|
|
||||||
* @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)
|
|
||||||
{
|
|
||||||
if ($template === null && $this instanceof $this->template_class) {
|
|
||||||
$template = $this;
|
|
||||||
}
|
|
||||||
if ($cache_id !== null && is_object($cache_id)) {
|
|
||||||
$parent = $cache_id;
|
|
||||||
$cache_id = null;
|
|
||||||
}
|
|
||||||
if ($parent === null && ($this instanceof Smarty || is_string($template))) {
|
|
||||||
$parent = $this;
|
|
||||||
}
|
|
||||||
// create template object if necessary
|
|
||||||
$_template = ($template instanceof $this->template_class)
|
|
||||||
? $template
|
|
||||||
: $this->smarty->createTemplate($template, $cache_id, $compile_id, $parent, false);
|
|
||||||
if ($this->smarty->debugging) {
|
|
||||||
Smarty_Internal_Debug::start_template($_template);
|
|
||||||
}
|
|
||||||
if (isset($_template->smarty->security_policy)) {
|
|
||||||
$_template->smarty->security_policy->startTemplate($_template);
|
|
||||||
}
|
|
||||||
// if called by Smarty object make sure we use current caching status
|
|
||||||
if ($this instanceof Smarty) {
|
|
||||||
$_template->caching = $this->caching;
|
|
||||||
}
|
|
||||||
// merge all variable scopes into template
|
|
||||||
if ($merge_tpl_vars) {
|
|
||||||
// save local variables
|
|
||||||
$save_tpl_vars = $_template->tpl_vars;
|
|
||||||
$save_config_vars = $_template->config_vars;
|
|
||||||
$ptr_array = array($_template);
|
|
||||||
$ptr = $_template;
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
$_template->tpl_vars = $tpl_vars;
|
|
||||||
$_template->config_vars = $config_vars;
|
|
||||||
}
|
|
||||||
// dummy local smarty variable
|
|
||||||
if (!isset($_template->tpl_vars['smarty'])) {
|
|
||||||
$_template->tpl_vars['smarty'] = new Smarty_Variable;
|
|
||||||
}
|
|
||||||
if (isset($_template->smarty->error_reporting)) {
|
|
||||||
$_smarty_old_error_level = error_reporting($_template->smarty->error_reporting);
|
|
||||||
}
|
|
||||||
// check URL debugging control
|
|
||||||
if (!$_template->smarty->debugging && $_template->smarty->debugging_ctrl == 'URL') {
|
|
||||||
Smarty_Internal_Debug::debugUrl($_template);
|
|
||||||
}
|
|
||||||
// checks if template exists
|
|
||||||
if (!$_template->source->exists) {
|
|
||||||
if ($_template->parent instanceof Smarty_Internal_Template) {
|
|
||||||
$parent_resource = " in '{$_template->parent->template_resource}'";
|
|
||||||
} else {
|
|
||||||
$parent_resource = '';
|
|
||||||
}
|
|
||||||
throw new SmartyException("Unable to load template {$_template->source->type} '{$_template->source->name}'{$parent_resource}");
|
|
||||||
}
|
|
||||||
// get rendered template
|
|
||||||
// disable caching for evaluated code
|
|
||||||
if ($_template->source->recompiled) {
|
|
||||||
$_template->caching = false;
|
|
||||||
}
|
|
||||||
// read from cache or render
|
|
||||||
if (!($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED) || !$_template->cached->valid) {
|
|
||||||
// render template (not loaded and not in cache)
|
|
||||||
if (!$_template->source->uncompiled) {
|
|
||||||
/** @var Smarty_Internal_Template $_smarty_tpl
|
|
||||||
* used in evaluated code
|
|
||||||
*/
|
|
||||||
$_smarty_tpl = $_template;
|
|
||||||
if ($_template->source->recompiled) {
|
|
||||||
$code = $_template->compiler->compileTemplate($_template);
|
|
||||||
if ($this->smarty->debugging) {
|
|
||||||
Smarty_Internal_Debug::start_render($_template);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
ob_start();
|
|
||||||
eval("?>" . $code);
|
|
||||||
unset($code);
|
|
||||||
}
|
|
||||||
catch (Exception $e) {
|
|
||||||
ob_get_clean();
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if (!$_template->compiled->exists || ($_template->smarty->force_compile && !$_template->compiled->isCompiled)) {
|
|
||||||
$_template->compileTemplateSource();
|
|
||||||
$code = file_get_contents($_template->compiled->filepath);
|
|
||||||
eval("?>" . $code);
|
|
||||||
unset($code);
|
|
||||||
$_template->compiled->loaded = true;
|
|
||||||
$_template->compiled->isCompiled = true;
|
|
||||||
}
|
|
||||||
if ($this->smarty->debugging) {
|
|
||||||
Smarty_Internal_Debug::start_render($_template);
|
|
||||||
}
|
|
||||||
if (!$_template->compiled->loaded) {
|
|
||||||
include($_template->compiled->filepath);
|
|
||||||
if ($_template->mustCompile) {
|
|
||||||
// recompile and load again
|
|
||||||
$_template->compileTemplateSource();
|
|
||||||
$code = file_get_contents($_template->compiled->filepath);
|
|
||||||
eval("?>" . $code);
|
|
||||||
unset($code);
|
|
||||||
$_template->compiled->isCompiled = true;
|
|
||||||
}
|
|
||||||
$_template->compiled->loaded = true;
|
|
||||||
} else {
|
|
||||||
$_template->decodeProperties($_template->compiled->_properties, false);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
ob_start();
|
|
||||||
if (empty($_template->properties['unifunc']) || !is_callable($_template->properties['unifunc'])) {
|
|
||||||
throw new SmartyException("Invalid compiled template for '{$_template->template_resource}'");
|
|
||||||
}
|
|
||||||
array_unshift($_template->_capture_stack, array());
|
|
||||||
//
|
|
||||||
// render compiled template
|
|
||||||
//
|
|
||||||
$_template->properties['unifunc']($_template);
|
|
||||||
// any unclosed {capture} tags ?
|
|
||||||
if (isset($_template->_capture_stack[0][0])) {
|
|
||||||
$_template->capture_error();
|
|
||||||
}
|
|
||||||
array_shift($_template->_capture_stack);
|
|
||||||
}
|
|
||||||
catch (Exception $e) {
|
|
||||||
ob_get_clean();
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ($_template->source->uncompiled) {
|
|
||||||
if ($this->smarty->debugging) {
|
|
||||||
Smarty_Internal_Debug::start_render($_template);
|
|
||||||
}
|
|
||||||
try {
|
|
||||||
ob_start();
|
|
||||||
$_template->source->renderUncompiled($_template);
|
|
||||||
}
|
|
||||||
catch (Exception $e) {
|
|
||||||
ob_get_clean();
|
|
||||||
throw $e;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
throw new SmartyException("Resource '$_template->source->type' must have 'renderUncompiled' method");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
$_output = ob_get_clean();
|
|
||||||
if (!$_template->source->recompiled && empty($_template->properties['file_dependency'][$_template->source->uid])) {
|
|
||||||
$_template->properties['file_dependency'][$_template->source->uid] = array($_template->source->filepath, $_template->source->timestamp, $_template->source->type);
|
|
||||||
}
|
|
||||||
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) {
|
|
||||||
$_template->parent->required_plugins[$code][$name][$type] = $data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ($this->smarty->debugging) {
|
|
||||||
Smarty_Internal_Debug::end_render($_template);
|
|
||||||
}
|
|
||||||
// write to cache when nessecary
|
|
||||||
if (!$_template->source->recompiled && ($_template->caching == Smarty::CACHING_LIFETIME_SAVED || $_template->caching == Smarty::CACHING_LIFETIME_CURRENT)) {
|
|
||||||
if ($this->smarty->debugging) {
|
|
||||||
Smarty_Internal_Debug::start_cache($_template);
|
|
||||||
}
|
|
||||||
$_template->properties['has_nocache_code'] = false;
|
|
||||||
// get text between non-cached items
|
|
||||||
$cache_split = preg_split("!/\*%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*\/(.+?)/\*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*/!s", $_output);
|
|
||||||
// get non-cached items
|
|
||||||
preg_match_all("!/\*%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*\/(.+?)/\*/%%SmartyNocache:{$_template->properties['nocache_hash']}%%\*/!s", $_output, $cache_parts);
|
|
||||||
$output = '';
|
|
||||||
// loop over items, stitch back together
|
|
||||||
foreach ($cache_split as $curr_idx => $curr_split) {
|
|
||||||
// escape PHP tags in template content
|
|
||||||
$output .= preg_replace('/(<%|%>|<\?php|<\?|\?>|<script\s+language\s*=\s*[\"\']?\s*php\s*[\"\']?\s*>)/', "<?php echo '\$1'; ?>\n", $curr_split);
|
|
||||||
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 .= $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']))) {
|
|
||||||
$output = Smarty_Internal_Filter_Handler::runFilter('output', $output, $_template);
|
|
||||||
}
|
|
||||||
// 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;
|
|
||||||
}
|
|
||||||
if ($this->smarty->debugging) {
|
|
||||||
Smarty_Internal_Debug::end_cache($_template);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// var_dump('renderTemplate', $_template->has_nocache_code, $_template->template_resource, $_template->properties['nocache_hash'], $_template->parent->properties['nocache_hash'], $_output);
|
|
||||||
if (!empty($_template->properties['nocache_hash']) && !empty($_template->parent->properties['nocache_hash'])) {
|
|
||||||
// replace nocache_hash
|
|
||||||
$_output = str_replace("{$_template->properties['nocache_hash']}", $_template->parent->properties['nocache_hash'], $_output);
|
|
||||||
$_template->parent->has_nocache_code = $_template->parent->has_nocache_code || $_template->has_nocache_code;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if ($this->smarty->debugging) {
|
|
||||||
Smarty_Internal_Debug::start_cache($_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;
|
|
||||||
}
|
|
||||||
if ($this->smarty->debugging) {
|
|
||||||
Smarty_Internal_Debug::end_cache($_template);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if ((!$this->caching || $_template->has_nocache_code || $_template->source->recompiled) && !$no_output_filter && (isset($this->smarty->autoload_filters['output']) || isset($this->smarty->registered_filters['output']))) {
|
|
||||||
$_output = Smarty_Internal_Filter_Handler::runFilter('output', $_output, $_template);
|
|
||||||
}
|
|
||||||
if (isset($this->error_reporting)) {
|
|
||||||
error_reporting($_smarty_old_error_level);
|
|
||||||
}
|
|
||||||
if (isset($_template->smarty->security_policy)) {
|
|
||||||
$_template->smarty->security_policy->exitTemplate($_template);
|
|
||||||
}
|
|
||||||
// display or fetch
|
|
||||||
if ($display) {
|
|
||||||
if ($this->caching && $this->cache_modified_check) {
|
|
||||||
$_isCached = $_template->isCached() && !$_template->has_nocache_code;
|
|
||||||
$_last_modified_date = @substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3);
|
|
||||||
if ($_isCached && $_template->cached->timestamp <= strtotime($_last_modified_date)) {
|
|
||||||
switch (PHP_SAPI) {
|
|
||||||
case 'cgi': // php-cgi < 5.3
|
|
||||||
case 'cgi-fcgi': // php-cgi >= 5.3
|
|
||||||
case 'fpm-fcgi': // php-fpm >= 5.3.3
|
|
||||||
header('Status: 304 Not Modified');
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 'cli':
|
|
||||||
if ( /* ^phpunit */
|
|
||||||
!empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS']) /* phpunit$ */
|
|
||||||
) {
|
|
||||||
$_SERVER['SMARTY_PHPUNIT_HEADERS'][] = '304 Not Modified';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
switch (PHP_SAPI) {
|
|
||||||
case 'cli':
|
|
||||||
if ( /* ^phpunit */
|
|
||||||
!empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS']) /* phpunit$ */
|
|
||||||
) {
|
|
||||||
$_SERVER['SMARTY_PHPUNIT_HEADERS'][] = 'Last-Modified: ' . gmdate('D, d M Y H:i:s', $_template->cached->timestamp) . ' GMT';
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $_template->cached->timestamp) . ' GMT');
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
echo $_output;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
echo $_output;
|
|
||||||
}
|
|
||||||
if ($this->smarty->debugging) {
|
|
||||||
Smarty_Internal_Debug::end_template($_template);
|
|
||||||
}
|
|
||||||
// debug output
|
|
||||||
if ($this->smarty->debugging) {
|
|
||||||
Smarty_Internal_Debug::display_debug($_template, true);
|
|
||||||
}
|
|
||||||
if ($merge_tpl_vars) {
|
|
||||||
// restore local variables
|
|
||||||
$_template->tpl_vars = $save_tpl_vars;
|
|
||||||
$_template->config_vars = $save_config_vars;
|
|
||||||
}
|
|
||||||
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
if ($merge_tpl_vars) {
|
|
||||||
// restore local variables
|
|
||||||
$_template->tpl_vars = $save_tpl_vars;
|
|
||||||
$_template->config_vars = $save_config_vars;
|
|
||||||
}
|
|
||||||
if ($this->smarty->debugging) {
|
|
||||||
Smarty_Internal_Debug::end_template($_template);
|
|
||||||
}
|
|
||||||
// return fetched content
|
|
||||||
return $_output;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* 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->fetch($template, $cache_id, $compile_id, $parent, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* test if cache is valid
|
* test if cache is valid
|
||||||
*
|
*
|
||||||
|
Reference in New Issue
Block a user