Performance enhancements.

This commit is contained in:
andrey
2002-02-15 20:50:44 +00:00
parent 120b1df0ed
commit 60617aa799
7 changed files with 230 additions and 212 deletions

2
NEWS
View File

@@ -1,3 +1,5 @@
- implemented several optimizations, speeding up Smarty significantly in
most cases. (Andrei)
- implemented plugin architecture. (Andrei) - implemented plugin architecture. (Andrei)
- added modifiers wordwrap and indent. (Monte) - added modifiers wordwrap and indent. (Monte)
- added support for 'If-Modified-Since' headers for cached content. (Monte) - added support for 'If-Modified-Since' headers for cached content. (Monte)

View File

@@ -96,7 +96,7 @@ class Smarty
var $cache_handler_func = null; // function used for cached content. this is var $cache_handler_func = null; // function used for cached content. this is
// an alternative to using the built-in file // an alternative to using the built-in file
// based caching. // based caching.
var $check_if_modified = true; // respect If-Modified-Since headers on cached content var $check_if_modified = false; // respect If-Modified-Since headers on cached content
var $default_template_handler_func = ''; // function to handle missing templates var $default_template_handler_func = ''; // function to handle missing templates
@@ -153,7 +153,7 @@ class Smarty
// internal vars // internal vars
var $_error_msg = false; // error messages. true/false var $_error_msg = false; // error messages. true/false
var $_tpl_vars = array(); // where assigned template vars are kept var $_tpl_vars = array(); // where assigned template vars are kept
var $_smarty_vars = array(); // stores run-time $smarty.* vars var $_smarty_vars = null; // stores run-time $smarty.* vars
var $_sections = array(); // keeps track of sections var $_sections = array(); // keeps track of sections
var $_foreach = array(); // keeps track of foreach blocks var $_foreach = array(); // keeps track of foreach blocks
var $_conf_obj = null; // configuration object var $_conf_obj = null; // configuration object
@@ -517,15 +517,15 @@ class Smarty
} }
if ($this->check_if_modified) { if ($this->check_if_modified) {
global $HTTP_IF_MODIFIED_SINCE; global $HTTP_IF_MODIFIED_SINCE;
$last_modified_date = substr($HTTP_IF_MODIFIED_SINCE,0,strpos($HTTP_IF_MODIFIED_SINCE,'GMT')+3); $last_modified_date = substr($HTTP_IF_MODIFIED_SINCE, 0, strpos($HTTP_IF_MODIFIED_SINCE, 'GMT') + 3);
$gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT'; $gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT';
if (@count($this->_cache_info['insert_tags']) == 0 if (@count($this->_cache_info['insert_tags']) == 0
&& $gmt_mtime == $last_modified_date) { && $gmt_mtime == $last_modified_date) {
header("HTTP/1.1 304 Not Modified"); header("HTTP/1.1 304 Not Modified");
} } else {
header("Last-Modified: ".$gmt_mtime);
}
} }
header("Content-Length: ".strlen($_smarty_results));
header("Last-Modified: ".$gmt_mtime);
echo $_smarty_results; echo $_smarty_results;
return true; return true;
} else { } else {
@@ -537,17 +537,6 @@ class Smarty
} }
} }
$this->_assign_smarty_interface();
if ($this->_conf_obj === null) {
/* Prepare the configuration object. */
if (!class_exists('Config_File'))
require_once SMARTY_DIR.'Config_File.class.php';
$this->_conf_obj = new Config_File($this->config_dir);
$this->_conf_obj->read_hidden = false;
} else
$this->_conf_obj->set_path($this->config_dir);
extract($this->_tpl_vars); extract($this->_tpl_vars);
/* Initialize config array. */ /* Initialize config array. */
@@ -623,30 +612,23 @@ class Smarty
\*======================================================================*/ \*======================================================================*/
function _assign_smarty_interface() function _assign_smarty_interface()
{ {
$egpcs = array('e' => 'env', if ($this->_smarty_vars !== null)
'g' => 'get', return;
'p' => 'post',
'c' => 'cookies', $globals_map = array('g' => 'HTTP_GET_VARS',
's' => 'server'); 'p' => 'HTTP_POST_VARS',
$globals_map = array('get' => 'HTTP_GET_VARS', 'c' => 'HTTP_COOKIE_VARS',
'post' => 'HTTP_POST_VARS', 's' => 'HTTP_SERVER_VARS',
'cookies' => 'HTTP_COOKIE_VARS', 'e' => 'HTTP_ENV_VARS');
'session' => 'HTTP_SESSION_VARS',
'server' => 'HTTP_SERVER_VARS',
'env' => 'HTTP_ENV_VARS');
$smarty = array('request' => array()); $smarty = array('request' => array());
foreach ($globals_map as $key => $array) {
$smarty[$key] = isset($GLOBALS[$array]) ? $GLOBALS[$array] : array();
}
foreach (preg_split('!!', strtolower($this->request_vars_order)) as $c) { foreach (preg_split('!!', strtolower($this->request_vars_order)) as $c) {
if (isset($egpcs[$c])) { if (isset($globals_map[$c])) {
$smarty['request'] = array_merge($smarty['request'], $smarty[$egpcs[$c]]); $smarty['request'] = array_merge($smarty['request'], $GLOBALS[$globals_map[$c]]);
} }
} }
$smarty['request'] = @array_merge($smarty['request'], $smarty['session']); $smarty['request'] = @array_merge($smarty['request'], $GLOBALS['HTTP_SESSION_VARS']);
$this->_smarty_vars = $smarty; $this->_smarty_vars = $smarty;
} }
@@ -801,7 +783,7 @@ function _generate_debug_output() {
function _process_template($tpl_file, $compile_path) function _process_template($tpl_file, $compile_path)
{ {
// test if template needs to be compiled // test if template needs to be compiled
if (!$this->force_compile && $this->_compiled_template_exists($compile_path)) { if (!$this->force_compile && file_exists($compile_path)) {
if (!$this->compile_check) { if (!$this->compile_check) {
// no need to check if the template needs recompiled // no need to check if the template needs recompiled
return true; return true;
@@ -811,7 +793,7 @@ function _generate_debug_output() {
$template_timestamp)) { $template_timestamp)) {
return false; return false;
} }
if ($template_timestamp <= $this->_fetch_compiled_template_timestamp($compile_path)) { if ($template_timestamp <= filemtime($compile_path)) {
// template not expired, no recompile // template not expired, no recompile
return true; return true;
} else { } else {
@@ -843,27 +825,6 @@ function _generate_debug_output() {
$this->_compile_id); $this->_compile_id);
} }
/*======================================================================*\
Function: _compiled_template_exists
Purpose:
\*======================================================================*/
function _compiled_template_exists($include_path)
{
// everything is in $compile_dir
return file_exists($include_path);
}
/*======================================================================*\
Function: _fetch_compiled_template_timestamp
Purpose:
\*======================================================================*/
function _fetch_compiled_template_timestamp($include_path)
{
// everything is in $compile_dir
return filemtime($include_path);
}
/*======================================================================*\ /*======================================================================*\
Function: _write_compiled_template Function: _write_compiled_template
Purpose: Purpose:
@@ -1059,6 +1020,16 @@ function _generate_debug_output() {
\*======================================================================*/ \*======================================================================*/
function _config_load($file, $section, $scope) function _config_load($file, $section, $scope)
{ {
if ($this->_conf_obj === null) {
/* Prepare the configuration object. */
if (!class_exists('Config_File'))
require_once SMARTY_DIR.'Config_File.class.php';
$this->_conf_obj = new Config_File($this->config_dir);
$this->_conf_obj->read_hidden = false;
} else {
$this->_conf_obj->set_path($this->config_dir);
}
if ($this->debugging) { if ($this->debugging) {
$debug_start_time = $this->_get_microtime(); $debug_start_time = $this->_get_microtime();
} }
@@ -1310,27 +1281,15 @@ function _run_insert_handler($args)
return true; return true;
} }
/*======================================================================*\
Function: _get_auto_base
Purpose: Get a base name for automatic files creation
\*======================================================================*/
function _get_auto_base($auto_base, $auto_source)
{
$source_md5 = md5($auto_source);
$res = $auto_base . '/' . substr($source_md5, 0, 2) . '/' . $source_md5;
return $res;
}
/*======================================================================*\ /*======================================================================*\
Function: _get_auto_filename Function: _get_auto_filename
Purpose: get a concrete filename for automagically created content Purpose: get a concrete filename for automagically created content
\*======================================================================*/ \*======================================================================*/
function _get_auto_filename($auto_base, $auto_source, $auto_id = null) function _get_auto_filename($auto_base, $auto_source, $auto_id = null)
{ {
$res = $this->_get_auto_base($auto_base, $auto_source) . $source_hash = crc32($auto_source);
'/' . md5($auto_id) . '.php'; $res = $auto_base . '/' . substr($source_hash, 0, 3) . '/' .
$source_hash . '/' . crc32($auto_id) . '.php';
return $res; return $res;
} }
@@ -1351,7 +1310,8 @@ function _run_insert_handler($args)
$tname = $this->_get_auto_filename($auto_base, $auto_source, $auto_id); $tname = $this->_get_auto_filename($auto_base, $auto_source, $auto_id);
$res = is_file($tname) && unlink( $tname); $res = is_file($tname) && unlink( $tname);
} else { } else {
$tname = $this->_get_auto_base($auto_base, $auto_source); $source_hash = crc32($auto_source);
$tname = $auto_base . '/' . substr($source_hash, 0, 3) . '/' . $source_hash;
$res = $this->_rmdir($tname); $res = $this->_rmdir($tname);
} }
} }
@@ -1418,7 +1378,7 @@ function _run_insert_handler($args)
$this->_cache_info['timestamp'] = time(); $this->_cache_info['timestamp'] = time();
// prepend the cache header info into cache file // prepend the cache header info into cache file
$results = 'SMARTY_CACHE_INFO_HEADER'.serialize($this->_cache_info)."\n".$results; $results = serialize($this->_cache_info)."\n".$results;
if (!empty($this->cache_handler_func)) { if (!empty($this->cache_handler_func)) {
// use cache_handler function // use cache_handler function
@@ -1444,16 +1404,22 @@ function _run_insert_handler($args)
\*======================================================================*/ \*======================================================================*/
function _read_cache_file($tpl_file, $cache_id, $compile_id, &$results) function _read_cache_file($tpl_file, $cache_id, $compile_id, &$results)
{ {
static $content_cache = array();
if ($this->force_compile || $this->cache_lifetime == 0) { if ($this->force_compile || $this->cache_lifetime == 0) {
// force compile enabled or cache lifetime is zero, always regenerate // force compile enabled or cache lifetime is zero, always regenerate
return false; return false;
} }
if (isset($content_cache["$tpl_file,$cache_id,$compile_id"])) {
list($results, $this->_cache_info) = $content_cache["$tpl_file,$cache_id,$compile_id"];
return true;
}
if (!empty($this->cache_handler_func)) { if (!empty($this->cache_handler_func)) {
// use cache_handler function // use cache_handler function
$funcname = $this->cache_handler_func; $funcname = $this->cache_handler_func;
$funcname('read', $this, $results, $tpl_file, $cache_id, $compile_id); $funcname('read', $this, $results, $tpl_file, $cache_id, $compile_id);
} else { } else {
// use local file cache // use local file cache
if (isset($compile_id) || isset($cache_id)) if (isset($compile_id) || isset($cache_id))
@@ -1463,7 +1429,6 @@ function _run_insert_handler($args)
$cache_file = $this->_get_auto_filename($this->cache_dir, $tpl_file, $auto_id); $cache_file = $this->_get_auto_filename($this->cache_dir, $tpl_file, $auto_id);
$results = $this->_read_file($cache_file); $results = $this->_read_file($cache_file);
} }
if (empty($results)) { if (empty($results)) {
@@ -1474,40 +1439,37 @@ function _run_insert_handler($args)
$cache_split = explode("\n", $results, 2); $cache_split = explode("\n", $results, 2);
$cache_header = $cache_split[0]; $cache_header = $cache_split[0];
if (substr($cache_header, 0, 24) == 'SMARTY_CACHE_INFO_HEADER') { $this->_cache_info = unserialize($cache_header);
$this->_cache_info = unserialize(substr($cache_header, 24)); $cache_timestamp = $this->_cache_info['timestamp'];
$cache_timestamp = $this->_cache_info['timestamp'];
if (time() - $cache_timestamp > $this->cache_lifetime) { if (time() - $cache_timestamp > $this->cache_lifetime) {
// cache expired, regenerate // cache expired, regenerate
return false; return false;
}
if ($this->compile_check) {
foreach ($this->_cache_info['template'] as $template_dep) {
$this->_fetch_template_info($template_dep, $template_source, $template_timestamp, false);
if ($cache_timestamp < $template_timestamp) {
// template file has changed, regenerate cache
return false;
}
} }
if ($this->compile_check) { if (isset($this->_cache_info['config'])) {
foreach ($this->_cache_info['template'] as $template_dep) { foreach ($this->_cache_info['config'] as $config_dep) {
$this->_fetch_template_info($template_dep, $template_source, $template_timestamp, false); if ($cache_timestamp < filemtime($this->config_dir.'/'.$config_dep)) {
if ($cache_timestamp < $template_timestamp) { // config file file has changed, regenerate cache
// template file has changed, regenerate cache
return false; return false;
} }
} }
if (isset($this->_cache_info['config'])) {
foreach ($this->_cache_info['config'] as $config_dep) {
if ($cache_timestamp < filemtime($this->config_dir.'/'.$config_dep)) {
// config file file has changed, regenerate cache
return false;
}
}
}
} }
$results = $cache_split[1];
return true;
} else {
// no cache info header, regenerate cache
return false;
} }
$results = $cache_split[1];
$content_cache["$tpl_file,$cache_id,$compile_id"] = array($results, $this->_cache_info);
return true;
} }
@@ -1688,6 +1650,10 @@ function _run_insert_handler($args)
} }
} }
function _init_conf_obj()
{
}
/*======================================================================*\ /*======================================================================*\
Function: quote_replace Function: quote_replace
Purpose: Quote subpattern references Purpose: Quote subpattern references

View File

@@ -50,6 +50,7 @@ class Smarty_Compiler extends Smarty {
var $_capture_stack = array(); // keeps track of nested capture buffers var $_capture_stack = array(); // keeps track of nested capture buffers
var $_plugin_info = array(); // keeps track of plugins to load var $_plugin_info = array(); // keeps track of plugins to load
var $_filters_loaded = false; var $_filters_loaded = false;
var $_init_smarty_vars = false;
/*======================================================================*\ /*======================================================================*\
@@ -201,6 +202,11 @@ class Smarty_Compiler extends Smarty {
$this->_plugin_info = array(); $this->_plugin_info = array();
} }
if ($this->_init_smarty_vars) {
$template_header .= "<?php \$this->_assign_smarty_interface(); ?>\n";
$this->_init_smarty_vars = false;
}
$template_compiled = $template_header . $template_compiled; $template_compiled = $template_header . $template_compiled;
return true; return true;
@@ -1209,14 +1215,50 @@ class Smarty_Compiler extends Smarty {
$compiled_ref = "\$this->_sections['$name']"; $compiled_ref = "\$this->_sections['$name']";
break; break;
/* These cases have to be handled at run-time. */
case 'env':
case 'get': case 'get':
array_shift($indexes);
$name = substr($indexes[0], 1);
$compiled_ref = "\$GLOBALS['HTTP_GET_VARS']['$name']";
break;
case 'post': case 'post':
array_shift($indexes);
$name = substr($indexes[0], 1);
$compiled_ref = "\$GLOBALS['HTTP_POST_VARS']['$name']";
break;
case 'cookies': case 'cookies':
array_shift($indexes);
$name = substr($indexes[0], 1);
$compiled_ref = "\$GLOBALS['HTTP_SERVER_VARS']['$name']";
break;
case 'env':
array_shift($indexes);
$name = substr($indexes[0], 1);
$compiled_ref = "\$GLOBALS['HTTP_ENV_VARS']['$name']";
break;
case 'server': case 'server':
array_shift($indexes);
$name = substr($indexes[0], 1);
$compiled_ref = "\$GLOBALS['HTTP_SERVER_VARS']['$name']";
break;
case 'session': case 'session':
array_shift($indexes);
$name = substr($indexes[0], 1);
$compiled_ref = "\$GLOBALS['HTTP_SESSION_VARS']['$name']";
break;
/*
* These cases are handled either at run-time or elsewhere in the
* compiler.
*/
case 'request': case 'request':
$this->_init_smarty_vars = true;
return null;
case 'capture': case 'capture':
return null; return null;

View File

@@ -96,7 +96,7 @@ class Smarty
var $cache_handler_func = null; // function used for cached content. this is var $cache_handler_func = null; // function used for cached content. this is
// an alternative to using the built-in file // an alternative to using the built-in file
// based caching. // based caching.
var $check_if_modified = true; // respect If-Modified-Since headers on cached content var $check_if_modified = false; // respect If-Modified-Since headers on cached content
var $default_template_handler_func = ''; // function to handle missing templates var $default_template_handler_func = ''; // function to handle missing templates
@@ -153,7 +153,7 @@ class Smarty
// internal vars // internal vars
var $_error_msg = false; // error messages. true/false var $_error_msg = false; // error messages. true/false
var $_tpl_vars = array(); // where assigned template vars are kept var $_tpl_vars = array(); // where assigned template vars are kept
var $_smarty_vars = array(); // stores run-time $smarty.* vars var $_smarty_vars = null; // stores run-time $smarty.* vars
var $_sections = array(); // keeps track of sections var $_sections = array(); // keeps track of sections
var $_foreach = array(); // keeps track of foreach blocks var $_foreach = array(); // keeps track of foreach blocks
var $_conf_obj = null; // configuration object var $_conf_obj = null; // configuration object
@@ -517,15 +517,15 @@ class Smarty
} }
if ($this->check_if_modified) { if ($this->check_if_modified) {
global $HTTP_IF_MODIFIED_SINCE; global $HTTP_IF_MODIFIED_SINCE;
$last_modified_date = substr($HTTP_IF_MODIFIED_SINCE,0,strpos($HTTP_IF_MODIFIED_SINCE,'GMT')+3); $last_modified_date = substr($HTTP_IF_MODIFIED_SINCE, 0, strpos($HTTP_IF_MODIFIED_SINCE, 'GMT') + 3);
$gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT'; $gmt_mtime = gmdate('D, d M Y H:i:s', $this->_cache_info['timestamp']).' GMT';
if (@count($this->_cache_info['insert_tags']) == 0 if (@count($this->_cache_info['insert_tags']) == 0
&& $gmt_mtime == $last_modified_date) { && $gmt_mtime == $last_modified_date) {
header("HTTP/1.1 304 Not Modified"); header("HTTP/1.1 304 Not Modified");
} } else {
header("Last-Modified: ".$gmt_mtime);
}
} }
header("Content-Length: ".strlen($_smarty_results));
header("Last-Modified: ".$gmt_mtime);
echo $_smarty_results; echo $_smarty_results;
return true; return true;
} else { } else {
@@ -537,17 +537,6 @@ class Smarty
} }
} }
$this->_assign_smarty_interface();
if ($this->_conf_obj === null) {
/* Prepare the configuration object. */
if (!class_exists('Config_File'))
require_once SMARTY_DIR.'Config_File.class.php';
$this->_conf_obj = new Config_File($this->config_dir);
$this->_conf_obj->read_hidden = false;
} else
$this->_conf_obj->set_path($this->config_dir);
extract($this->_tpl_vars); extract($this->_tpl_vars);
/* Initialize config array. */ /* Initialize config array. */
@@ -623,30 +612,23 @@ class Smarty
\*======================================================================*/ \*======================================================================*/
function _assign_smarty_interface() function _assign_smarty_interface()
{ {
$egpcs = array('e' => 'env', if ($this->_smarty_vars !== null)
'g' => 'get', return;
'p' => 'post',
'c' => 'cookies', $globals_map = array('g' => 'HTTP_GET_VARS',
's' => 'server'); 'p' => 'HTTP_POST_VARS',
$globals_map = array('get' => 'HTTP_GET_VARS', 'c' => 'HTTP_COOKIE_VARS',
'post' => 'HTTP_POST_VARS', 's' => 'HTTP_SERVER_VARS',
'cookies' => 'HTTP_COOKIE_VARS', 'e' => 'HTTP_ENV_VARS');
'session' => 'HTTP_SESSION_VARS',
'server' => 'HTTP_SERVER_VARS',
'env' => 'HTTP_ENV_VARS');
$smarty = array('request' => array()); $smarty = array('request' => array());
foreach ($globals_map as $key => $array) {
$smarty[$key] = isset($GLOBALS[$array]) ? $GLOBALS[$array] : array();
}
foreach (preg_split('!!', strtolower($this->request_vars_order)) as $c) { foreach (preg_split('!!', strtolower($this->request_vars_order)) as $c) {
if (isset($egpcs[$c])) { if (isset($globals_map[$c])) {
$smarty['request'] = array_merge($smarty['request'], $smarty[$egpcs[$c]]); $smarty['request'] = array_merge($smarty['request'], $GLOBALS[$globals_map[$c]]);
} }
} }
$smarty['request'] = @array_merge($smarty['request'], $smarty['session']); $smarty['request'] = @array_merge($smarty['request'], $GLOBALS['HTTP_SESSION_VARS']);
$this->_smarty_vars = $smarty; $this->_smarty_vars = $smarty;
} }
@@ -801,7 +783,7 @@ function _generate_debug_output() {
function _process_template($tpl_file, $compile_path) function _process_template($tpl_file, $compile_path)
{ {
// test if template needs to be compiled // test if template needs to be compiled
if (!$this->force_compile && $this->_compiled_template_exists($compile_path)) { if (!$this->force_compile && file_exists($compile_path)) {
if (!$this->compile_check) { if (!$this->compile_check) {
// no need to check if the template needs recompiled // no need to check if the template needs recompiled
return true; return true;
@@ -811,7 +793,7 @@ function _generate_debug_output() {
$template_timestamp)) { $template_timestamp)) {
return false; return false;
} }
if ($template_timestamp <= $this->_fetch_compiled_template_timestamp($compile_path)) { if ($template_timestamp <= filemtime($compile_path)) {
// template not expired, no recompile // template not expired, no recompile
return true; return true;
} else { } else {
@@ -843,27 +825,6 @@ function _generate_debug_output() {
$this->_compile_id); $this->_compile_id);
} }
/*======================================================================*\
Function: _compiled_template_exists
Purpose:
\*======================================================================*/
function _compiled_template_exists($include_path)
{
// everything is in $compile_dir
return file_exists($include_path);
}
/*======================================================================*\
Function: _fetch_compiled_template_timestamp
Purpose:
\*======================================================================*/
function _fetch_compiled_template_timestamp($include_path)
{
// everything is in $compile_dir
return filemtime($include_path);
}
/*======================================================================*\ /*======================================================================*\
Function: _write_compiled_template Function: _write_compiled_template
Purpose: Purpose:
@@ -1059,6 +1020,16 @@ function _generate_debug_output() {
\*======================================================================*/ \*======================================================================*/
function _config_load($file, $section, $scope) function _config_load($file, $section, $scope)
{ {
if ($this->_conf_obj === null) {
/* Prepare the configuration object. */
if (!class_exists('Config_File'))
require_once SMARTY_DIR.'Config_File.class.php';
$this->_conf_obj = new Config_File($this->config_dir);
$this->_conf_obj->read_hidden = false;
} else {
$this->_conf_obj->set_path($this->config_dir);
}
if ($this->debugging) { if ($this->debugging) {
$debug_start_time = $this->_get_microtime(); $debug_start_time = $this->_get_microtime();
} }
@@ -1310,27 +1281,15 @@ function _run_insert_handler($args)
return true; return true;
} }
/*======================================================================*\
Function: _get_auto_base
Purpose: Get a base name for automatic files creation
\*======================================================================*/
function _get_auto_base($auto_base, $auto_source)
{
$source_md5 = md5($auto_source);
$res = $auto_base . '/' . substr($source_md5, 0, 2) . '/' . $source_md5;
return $res;
}
/*======================================================================*\ /*======================================================================*\
Function: _get_auto_filename Function: _get_auto_filename
Purpose: get a concrete filename for automagically created content Purpose: get a concrete filename for automagically created content
\*======================================================================*/ \*======================================================================*/
function _get_auto_filename($auto_base, $auto_source, $auto_id = null) function _get_auto_filename($auto_base, $auto_source, $auto_id = null)
{ {
$res = $this->_get_auto_base($auto_base, $auto_source) . $source_hash = crc32($auto_source);
'/' . md5($auto_id) . '.php'; $res = $auto_base . '/' . substr($source_hash, 0, 3) . '/' .
$source_hash . '/' . crc32($auto_id) . '.php';
return $res; return $res;
} }
@@ -1351,7 +1310,8 @@ function _run_insert_handler($args)
$tname = $this->_get_auto_filename($auto_base, $auto_source, $auto_id); $tname = $this->_get_auto_filename($auto_base, $auto_source, $auto_id);
$res = is_file($tname) && unlink( $tname); $res = is_file($tname) && unlink( $tname);
} else { } else {
$tname = $this->_get_auto_base($auto_base, $auto_source); $source_hash = crc32($auto_source);
$tname = $auto_base . '/' . substr($source_hash, 0, 3) . '/' . $source_hash;
$res = $this->_rmdir($tname); $res = $this->_rmdir($tname);
} }
} }
@@ -1418,7 +1378,7 @@ function _run_insert_handler($args)
$this->_cache_info['timestamp'] = time(); $this->_cache_info['timestamp'] = time();
// prepend the cache header info into cache file // prepend the cache header info into cache file
$results = 'SMARTY_CACHE_INFO_HEADER'.serialize($this->_cache_info)."\n".$results; $results = serialize($this->_cache_info)."\n".$results;
if (!empty($this->cache_handler_func)) { if (!empty($this->cache_handler_func)) {
// use cache_handler function // use cache_handler function
@@ -1444,16 +1404,22 @@ function _run_insert_handler($args)
\*======================================================================*/ \*======================================================================*/
function _read_cache_file($tpl_file, $cache_id, $compile_id, &$results) function _read_cache_file($tpl_file, $cache_id, $compile_id, &$results)
{ {
static $content_cache = array();
if ($this->force_compile || $this->cache_lifetime == 0) { if ($this->force_compile || $this->cache_lifetime == 0) {
// force compile enabled or cache lifetime is zero, always regenerate // force compile enabled or cache lifetime is zero, always regenerate
return false; return false;
} }
if (isset($content_cache["$tpl_file,$cache_id,$compile_id"])) {
list($results, $this->_cache_info) = $content_cache["$tpl_file,$cache_id,$compile_id"];
return true;
}
if (!empty($this->cache_handler_func)) { if (!empty($this->cache_handler_func)) {
// use cache_handler function // use cache_handler function
$funcname = $this->cache_handler_func; $funcname = $this->cache_handler_func;
$funcname('read', $this, $results, $tpl_file, $cache_id, $compile_id); $funcname('read', $this, $results, $tpl_file, $cache_id, $compile_id);
} else { } else {
// use local file cache // use local file cache
if (isset($compile_id) || isset($cache_id)) if (isset($compile_id) || isset($cache_id))
@@ -1463,7 +1429,6 @@ function _run_insert_handler($args)
$cache_file = $this->_get_auto_filename($this->cache_dir, $tpl_file, $auto_id); $cache_file = $this->_get_auto_filename($this->cache_dir, $tpl_file, $auto_id);
$results = $this->_read_file($cache_file); $results = $this->_read_file($cache_file);
} }
if (empty($results)) { if (empty($results)) {
@@ -1474,40 +1439,37 @@ function _run_insert_handler($args)
$cache_split = explode("\n", $results, 2); $cache_split = explode("\n", $results, 2);
$cache_header = $cache_split[0]; $cache_header = $cache_split[0];
if (substr($cache_header, 0, 24) == 'SMARTY_CACHE_INFO_HEADER') { $this->_cache_info = unserialize($cache_header);
$this->_cache_info = unserialize(substr($cache_header, 24)); $cache_timestamp = $this->_cache_info['timestamp'];
$cache_timestamp = $this->_cache_info['timestamp'];
if (time() - $cache_timestamp > $this->cache_lifetime) { if (time() - $cache_timestamp > $this->cache_lifetime) {
// cache expired, regenerate // cache expired, regenerate
return false; return false;
}
if ($this->compile_check) {
foreach ($this->_cache_info['template'] as $template_dep) {
$this->_fetch_template_info($template_dep, $template_source, $template_timestamp, false);
if ($cache_timestamp < $template_timestamp) {
// template file has changed, regenerate cache
return false;
}
} }
if ($this->compile_check) { if (isset($this->_cache_info['config'])) {
foreach ($this->_cache_info['template'] as $template_dep) { foreach ($this->_cache_info['config'] as $config_dep) {
$this->_fetch_template_info($template_dep, $template_source, $template_timestamp, false); if ($cache_timestamp < filemtime($this->config_dir.'/'.$config_dep)) {
if ($cache_timestamp < $template_timestamp) { // config file file has changed, regenerate cache
// template file has changed, regenerate cache
return false; return false;
} }
} }
if (isset($this->_cache_info['config'])) {
foreach ($this->_cache_info['config'] as $config_dep) {
if ($cache_timestamp < filemtime($this->config_dir.'/'.$config_dep)) {
// config file file has changed, regenerate cache
return false;
}
}
}
} }
$results = $cache_split[1];
return true;
} else {
// no cache info header, regenerate cache
return false;
} }
$results = $cache_split[1];
$content_cache["$tpl_file,$cache_id,$compile_id"] = array($results, $this->_cache_info);
return true;
} }
@@ -1688,6 +1650,10 @@ function _run_insert_handler($args)
} }
} }
function _init_conf_obj()
{
}
/*======================================================================*\ /*======================================================================*\
Function: quote_replace Function: quote_replace
Purpose: Quote subpattern references Purpose: Quote subpattern references

View File

@@ -50,6 +50,7 @@ class Smarty_Compiler extends Smarty {
var $_capture_stack = array(); // keeps track of nested capture buffers var $_capture_stack = array(); // keeps track of nested capture buffers
var $_plugin_info = array(); // keeps track of plugins to load var $_plugin_info = array(); // keeps track of plugins to load
var $_filters_loaded = false; var $_filters_loaded = false;
var $_init_smarty_vars = false;
/*======================================================================*\ /*======================================================================*\
@@ -201,6 +202,11 @@ class Smarty_Compiler extends Smarty {
$this->_plugin_info = array(); $this->_plugin_info = array();
} }
if ($this->_init_smarty_vars) {
$template_header .= "<?php \$this->_assign_smarty_interface(); ?>\n";
$this->_init_smarty_vars = false;
}
$template_compiled = $template_header . $template_compiled; $template_compiled = $template_header . $template_compiled;
return true; return true;
@@ -1209,14 +1215,50 @@ class Smarty_Compiler extends Smarty {
$compiled_ref = "\$this->_sections['$name']"; $compiled_ref = "\$this->_sections['$name']";
break; break;
/* These cases have to be handled at run-time. */
case 'env':
case 'get': case 'get':
array_shift($indexes);
$name = substr($indexes[0], 1);
$compiled_ref = "\$GLOBALS['HTTP_GET_VARS']['$name']";
break;
case 'post': case 'post':
array_shift($indexes);
$name = substr($indexes[0], 1);
$compiled_ref = "\$GLOBALS['HTTP_POST_VARS']['$name']";
break;
case 'cookies': case 'cookies':
array_shift($indexes);
$name = substr($indexes[0], 1);
$compiled_ref = "\$GLOBALS['HTTP_SERVER_VARS']['$name']";
break;
case 'env':
array_shift($indexes);
$name = substr($indexes[0], 1);
$compiled_ref = "\$GLOBALS['HTTP_ENV_VARS']['$name']";
break;
case 'server': case 'server':
array_shift($indexes);
$name = substr($indexes[0], 1);
$compiled_ref = "\$GLOBALS['HTTP_SERVER_VARS']['$name']";
break;
case 'session': case 'session':
array_shift($indexes);
$name = substr($indexes[0], 1);
$compiled_ref = "\$GLOBALS['HTTP_SESSION_VARS']['$name']";
break;
/*
* These cases are handled either at run-time or elsewhere in the
* compiler.
*/
case 'request': case 'request':
$this->_init_smarty_vars = true;
return null;
case 'capture': case 'capture':
return null; return null;

View File

@@ -18,7 +18,7 @@ function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
} }
return $results; return $results;
} else { } else {
if (empty($var)) { if (empty($var) && $var != "0") {
return '<i>empty</i>'; return '<i>empty</i>';
} }
if (strlen($var) > $length ) { if (strlen($var) > $length ) {

View File

@@ -18,7 +18,7 @@ function smarty_modifier_debug_print_var($var, $depth = 0, $length = 40)
} }
return $results; return $results;
} else { } else {
if (empty($var)) { if (empty($var) && $var != "0") {
return '<i>empty</i>'; return '<i>empty</i>';
} }
if (strlen($var) > $length ) { if (strlen($var) > $length ) {