added $cacheable-parameter to register_function() and register_block()

This commit is contained in:
messju
2003-06-18 23:01:42 +00:00
parent 022621aa40
commit 4596b0d794
8 changed files with 220 additions and 19 deletions

2
NEWS
View File

@@ -1,3 +1,5 @@
- added $cacheable-parameter with default=true to register_function()
and register_block() (messju)
- add math speedup to core (Dominik, Monte) - add math speedup to core (Dominik, Monte)
- fix newlines for tags without template output (Monte) - fix newlines for tags without template output (Monte)
- added config-option "request_use_auto_globals" to make auto-globals be - added config-option "request_use_auto_globals" to make auto-globals be

View File

@@ -563,6 +563,10 @@ reques * @var string
'resource' => array(), 'resource' => array(),
'insert' => array()); 'insert' => array());
var $_cache_serial = null;
var $_cache_serials = array();
/**#@-*/ /**#@-*/
/** /**
* The class constructor. * The class constructor.
@@ -708,10 +712,10 @@ reques * @var string
* @param string $function the name of the template function * @param string $function the name of the template function
* @param string $function_impl the name of the PHP function to register * @param string $function_impl the name of the PHP function to register
*/ */
function register_function($function, $function_impl) function register_function($function, $function_impl, $cacheable=true)
{ {
$this->_plugins['function'][$function] = $this->_plugins['function'][$function] =
array($function_impl, null, null, false); array($function_impl, null, null, false, $cacheable);
} }
/** /**
@@ -758,10 +762,10 @@ reques * @var string
* @param string $block name of template block * @param string $block name of template block
* @param string $block_impl PHP function to register * @param string $block_impl PHP function to register
*/ */
function register_block($block, $block_impl) function register_block($block, $block_impl, $cacheable=true)
{ {
$this->_plugins['block'][$block] = $this->_plugins['block'][$block] =
array($block_impl, null, null, false); array($block_impl, null, null, false, $cacheable);
} }
/** /**
@@ -1195,6 +1199,13 @@ reques * @var string
require_once(SMARTY_DIR . 'core/core.process_cached_inserts.php'); require_once(SMARTY_DIR . 'core/core.process_cached_inserts.php');
$_smarty_results = smarty_core_process_cached_inserts($_params, $this); $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
} }
if (@count($this->_cache_info['cache_serials'])) {
$_params = array('results' => $_smarty_results);
require_once(SMARTY_DIR . 'core/core.process_compiled_include.php');
$_smarty_results = smarty_core_process_compiled_include($_params, $this);
}
if ($display) { if ($display) {
if ($this->debugging) if ($this->debugging)
{ {
@@ -1209,6 +1220,7 @@ reques * @var string
$_last_modified_date = substr($GLOBALS['HTTP_SERVER_VARS']['HTTP_IF_MODIFIED_SINCE'], 0, strpos($GLOBALS['HTTP_SERVER_VARS']['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); $_last_modified_date = substr($GLOBALS['HTTP_SERVER_VARS']['HTTP_IF_MODIFIED_SINCE'], 0, strpos($GLOBALS['HTTP_SERVER_VARS']['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
&& !$this->_cache_serials
&& $_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 { } else {
@@ -1279,6 +1291,13 @@ reques * @var string
smarty_core_write_cache_file($_params, $this); smarty_core_write_cache_file($_params, $this);
require_once(SMARTY_DIR . 'core/core.process_cached_inserts.php'); require_once(SMARTY_DIR . 'core/core.process_cached_inserts.php');
$_smarty_results = smarty_core_process_cached_inserts($_params, $this); $_smarty_results = smarty_core_process_cached_inserts($_params, $this);
if ($this->_cache_serials) {
// strip nocache-tags from output
$_smarty_results = preg_replace('!(\{/?nocache\:[0-9a-f]{32}#\d+\})!s'
,''
,$_smarty_results);
}
// restore initial cache_info // restore initial cache_info
$this->_cache_info = array_pop($_cache_info); $this->_cache_info = array_pop($_cache_info);
} }
@@ -1490,10 +1509,21 @@ reques * @var string
$smarty_compiler->request_use_auto_globals = $this->request_use_auto_globals; $smarty_compiler->request_use_auto_globals = $this->request_use_auto_globals;
$smarty_compiler->_cache_serial = null;
$smarty_compiler->_cache_include = substr($compile_path, 0, -4).'.inc';
if ($smarty_compiler->_compile_file($tpl_file, $_file_source, $_file_compiled)) { if ($smarty_compiler->_compile_file($tpl_file, $_file_source, $_file_compiled)) {
$_params = array('compile_path' => $compile_path, 'file_compiled' => $_file_compiled, 'file_timestamp' => $_file_timestamp); $_params = array('compile_path' => $compile_path, 'file_compiled' => $_file_compiled, 'file_timestamp' => $_file_timestamp);
require_once(SMARTY_DIR . 'core/core.write_compiled_template.php'); require_once(SMARTY_DIR . 'core/core.write_compiled_template.php');
smarty_core_write_compiled_template($_params, $this); smarty_core_write_compiled_template($_params, $this);
// if a _cache_serial was set, we also have to write an include-file:
if ($this->_cache_serial = $smarty_compiler->_cache_serial) {
$_params['plugins_code'] = $smarty_compiler->_plugins_code;
$_params['include_file_path'] = $smarty_compiler->_cache_include;
require_once(SMARTY_DIR . 'core/core.write_compiled_include.php');
smarty_core_write_compiled_include($_params, $this);
}
return true; return true;
} else { } else {
$this->trigger_error($smarty_compiler->_error_msg); $this->trigger_error($smarty_compiler->_error_msg);
@@ -1719,7 +1749,8 @@ reques * @var string
} }
/** /**
* check if the function or method exists * @return bool * check if the function or method exists
* @return bool
*/ */
function _plugin_implementation_exists($function) function _plugin_implementation_exists($function)
{ {
@@ -1727,6 +1758,22 @@ reques * @var string
method_exists($function[0], $function[1]) : function_exists($function); method_exists($function[0], $function[1]) : function_exists($function);
} }
/**#@-*/ /**#@-*/
/**
* callback function for preg_replace, to call a non-cacheable block
* @return string
*/
function _process_compiled_include_callback($match) {
$_func = '_smarty_tplfunc_'.$match[2].'_'.$match[3];
ob_start();
$_func($this);
$_ret = ob_get_contents();
ob_end_clean();
return $_ret;
}
} }
/* vim: set expandtab: */ /* vim: set expandtab: */

View File

@@ -79,6 +79,12 @@ class Smarty_Compiler extends Smarty {
var $_obj_start_regexp = null; var $_obj_start_regexp = null;
var $_obj_params_regexp = null; var $_obj_params_regexp = null;
var $_obj_call_regexp = null; var $_obj_call_regexp = null;
var $_cacheable_state = 0;
var $_nocache_count = 0;
var $_cache_serial = null;
var $_cache_include = null;
/**#@-*/ /**#@-*/
/** /**
* The class constructor. * The class constructor.
@@ -325,6 +331,10 @@ class Smarty_Compiler extends Smarty {
$file_compiled = substr($file_compiled, 0, -1); $file_compiled = substr($file_compiled, 0, -1);
} }
if (!empty($this->_cache_serial)) {
$file_compiled = "<?php \$this->_cache_serials['".$this->_cache_include."'] = '".$this->_cache_serial."'; ?>" . $file_compiled;
}
// remove unnecessary close/open tags // remove unnecessary close/open tags
$file_compiled = preg_replace('!\?>\n?<\?php!', '', $file_compiled); $file_compiled = preg_replace('!\?>\n?<\?php!', '', $file_compiled);
@@ -347,6 +357,7 @@ class Smarty_Compiler extends Smarty {
$template_header .= " compiled from ".$tpl_file." */ ?>\n"; $template_header .= " compiled from ".$tpl_file." */ ?>\n";
/* Emit code to load needed plugins. */ /* Emit code to load needed plugins. */
$this->_plugins_code = '';
if (count($this->_plugin_info)) { if (count($this->_plugin_info)) {
$_plugins_params = "array('plugins' => array("; $_plugins_params = "array('plugins' => array(";
foreach ($this->_plugin_info as $plugin_type => $plugins) { foreach ($this->_plugin_info as $plugin_type => $plugins) {
@@ -359,6 +370,7 @@ class Smarty_Compiler extends Smarty {
$plugins_code = "<?php require_once(SMARTY_DIR . 'core/core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n"; $plugins_code = "<?php require_once(SMARTY_DIR . 'core/core.load_plugins.php');\nsmarty_core_load_plugins($_plugins_params, \$this); ?>\n";
$template_header .= $plugins_code; $template_header .= $plugins_code;
$this->_plugin_info = array(); $this->_plugin_info = array();
$this->_plugins_code = $plugins_code;
} }
if ($this->_init_smarty_vars) { if ($this->_init_smarty_vars) {
@@ -545,7 +557,7 @@ class Smarty_Compiler extends Smarty {
$message = "plugin function $plugin_func() not found in $plugin_file\n"; $message = "plugin function $plugin_func() not found in $plugin_file\n";
$have_function = false; $have_function = false;
} else { } else {
$this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null); $this->_plugins['compiler'][$tag_command] = array($plugin_func, null, null, null, true);
} }
} }
@@ -559,7 +571,9 @@ class Smarty_Compiler extends Smarty {
if ($have_function) { if ($have_function) {
$output = call_user_func_array($plugin_func, array($tag_args, &$this)); $output = call_user_func_array($plugin_func, array($tag_args, &$this));
if($output != '') { if($output != '') {
$output = '<?php ' . $output . ' ?>'; $output = '<?php ' . $this->_push_cacheable_state('compiler', $tag_command)
. $output
. $this->_pop_cacheable_state('compiler', $tag_command) . ' ?>';
} }
} else { } else {
$this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__); $this->_syntax_error($message, E_USER_WARNING, __FILE__, __LINE__);
@@ -645,7 +659,8 @@ class Smarty_Compiler extends Smarty {
$arg_list[] = "'$arg_name' => $arg_value"; $arg_list[] = "'$arg_name' => $arg_value";
} }
$output = "<?php \$this->_tag_stack[] = array('$tag_command', array(".implode(',', (array)$arg_list).')); '; $output = '<?php ' . $this->_push_cacheable_state('block', $tag_command);
$output .= "\$this->_tag_stack[] = array('$tag_command', array(".implode(',', (array)$arg_list).')); ';
$output .= $this->_compile_plugin_call('block', $tag_command).'(array('.implode(',', (array)$arg_list).'), null, $this, $_block_repeat=true);'; $output .= $this->_compile_plugin_call('block', $tag_command).'(array('.implode(',', (array)$arg_list).'), null, $this, $_block_repeat=true);';
$output .= 'while ($_block_repeat) { ob_start(); ?>'; $output .= 'while ($_block_repeat) { ob_start(); ?>';
} else { } else {
@@ -655,7 +670,7 @@ class Smarty_Compiler extends Smarty {
$this->_parse_modifiers($_out_tag_text, $tag_modifier); $this->_parse_modifiers($_out_tag_text, $tag_modifier);
} }
$output .= 'echo '.$_out_tag_text.'; } '; $output .= 'echo '.$_out_tag_text.'; } ';
$output .= " array_pop(\$this->_tag_stack); ?>"; $output .= " array_pop(\$this->_tag_stack); " . $this->_pop_cacheable_state('block', $tag_command) . '?>';
} }
return true; return true;
@@ -684,14 +699,14 @@ class Smarty_Compiler extends Smarty {
$arg_value = 'null'; $arg_value = 'null';
$arg_list[] = "'$arg_name' => $arg_value"; $arg_list[] = "'$arg_name' => $arg_value";
} }
$_return = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', (array)$arg_list)."), \$this)"; $_return = $this->_compile_plugin_call('function', $tag_command).'(array('.implode(',', (array)$arg_list)."), \$this)";
if($tag_modifier != '') { if($tag_modifier != '') {
$this->_parse_modifiers($return, $tag_modifier); $this->_parse_modifiers($return, $tag_modifier);
} }
if($_return != '') { if($_return != '') {
$_return = '<?php echo ' . $_return . ' ; ?>'; $_return = '<?php ' . $this->_push_cacheable_state('function', $tag_command)
. 'echo ' . $_return . ';' . $this->_pop_cacheable_state('function', $tag_command) . "?>\n";
} }
return $_return; return $_return;
@@ -1084,6 +1099,7 @@ class Smarty_Compiler extends Smarty {
* @param string $tag_args * @param string $tag_args
* @return string * @return string
*/ */
function _compile_capture_tag($start, $tag_args = '') function _compile_capture_tag($start, $tag_args = '')
{ {
$attrs = $this->_parse_attrs($tag_args); $attrs = $this->_parse_attrs($tag_args);
@@ -1963,6 +1979,41 @@ class Smarty_Compiler extends Smarty {
trigger_error('Smarty: [in ' . $this->_current_file . ' line ' . trigger_error('Smarty: [in ' . $this->_current_file . ' line ' .
$this->_current_line_no . "]: syntax error: $error_msg$info", $error_type); $this->_current_line_no . "]: syntax error: $error_msg$info", $error_type);
} }
/**
* check if the compilation changes from cacheable to
* non-cacheable state with the beginning of the current
* plugin. return php-code to reflect the transition.
* @return string
*/
function _push_cacheable_state($type, $name) {
$_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
if ($_cacheable
|| $this->_cacheable_state++) return '';
if (!isset($this->_cache_serial)) $this->_cache_serial = md5(uniqid('Smarty'));
$_ret = 'if ($this->caching) { echo \'{nocache:'
. $this->_cache_serial . '#' . $this->_nocache_count
. '}\';}';
return $_ret;
}
/**
* check if the compilation changes from non-cacheable to
* cacheable state with the end of the current plugin return
* php-code to reflect the transition.
* @return string
*/
function _pop_cacheable_state($type, $name) {
$_cacheable = !isset($this->_plugins[$type][$name]) || $this->_plugins[$type][$name][4];
if ($_cacheable
|| --$this->_cacheable_state>0) return '';
return 'if ($this->caching) { echo \'{/nocache:'
. $this->_cache_serial . '#' . ($this->_nocache_count++)
. '}\';}';
}
} }
/** /**

View File

@@ -38,6 +38,7 @@ function smarty_core_load_plugins($params, &$this)
$_plugin[1] = $_tpl_file; $_plugin[1] = $_tpl_file;
$_plugin[2] = $_tpl_line; $_plugin[2] = $_tpl_line;
$_plugin[3] = true; $_plugin[3] = true;
$_plugin[4] = true; /* cacheable */
} }
} }
continue; continue;
@@ -48,7 +49,7 @@ function smarty_core_load_plugins($params, &$this)
*/ */
$_plugin_func = 'insert_' . $_name; $_plugin_func = 'insert_' . $_name;
if (function_exists($_plugin_func)) { if (function_exists($_plugin_func)) {
$_plugin = array($_plugin_func, $_tpl_file, $_tpl_line, true); $_plugin = array($_plugin_func, $_tpl_file, $_tpl_line, true, false);
continue; continue;
} }
} }
@@ -111,7 +112,7 @@ function smarty_core_load_plugins($params, &$this)
} }
if ($_found) { if ($_found) {
$this->_plugins[$_type][$_name] = array($_plugin_func, $_tpl_file, $_tpl_line, true); $this->_plugins[$_type][$_name] = array($_plugin_func, $_tpl_file, $_tpl_line, true, true);
} else { } else {
// output error // output error
$this->_trigger_fatal_error('[plugin] ' . $_message, $_tpl_file, $_tpl_line, __FILE__, __LINE__); $this->_trigger_fatal_error('[plugin] ' . $_message, $_tpl_file, $_tpl_line, __FILE__, __LINE__);

View File

@@ -0,0 +1,29 @@
<?php
/**
* Smarty plugin
* @package Smarty
* @subpackage plugins
*/
/**
* Replace nocache-tags by results of the corresponding non-cacheable
* functions and return it
*
* @param string $compiled_tpl
* @param string $cached_source
* @return string
*/
function smarty_core_process_compiled_include($params, &$this)
{
$_return = $params['results'];
foreach ($this->_cache_serials as $_include_file_path=>$_cache_serial) {
include_once($_include_file_path);
$_return = preg_replace_callback('!(\{nocache\:('.$_cache_serial.')#(\d+)\})!s',
array(&$this, '_process_compiled_include_callback'),
$_return);
}
return $_return;
}
?>

View File

@@ -81,7 +81,7 @@ function smarty_core_read_cache_file(&$params, &$this)
if (isset($this->_cache_info['config'])) { if (isset($this->_cache_info['config'])) {
require_once(SMARTY_DIR . 'core/core.fetch_file_info.php'); require_once(SMARTY_DIR . 'core/core.fetch_file_info.php');
foreach (array_keys($this->_cache_info['config']) as $_config_dep) { foreach (array_keys($this->_cache_info['config']) as $_config_dep) {
$_params = array('file_path' => $this->config_dir . '/' . $_config_dep); $_params = array('file_path' => $_config_dep);
smarty_core_fetch_file_info($_params, $this); smarty_core_fetch_file_info($_params, $this);
if ($this->_cache_info['timestamp'] < $_params['file_timestamp']) { if ($this->_cache_info['timestamp'] < $_params['file_timestamp']) {
// config file has changed, regenerate cache // config file has changed, regenerate cache
@@ -91,6 +91,9 @@ function smarty_core_read_cache_file(&$params, &$this)
} }
} }
$this->_cache_serials = array_merge($this->_cache_serials,
$this->_cache_info['cache_serials']);
$params['results'] = $cache_split[1]; $params['results'] = $cache_split[1];
$content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $this->_cache_info); $content_cache[$params['tpl_file'].','.$params['cache_id'].','.$params['compile_id']] = array($params['results'], $this->_cache_info);

View File

@@ -41,6 +41,14 @@ function smarty_core_write_cache_file($params, &$this)
$this->_cache_info['expires'] = -1; $this->_cache_info['expires'] = -1;
} }
// collapse {nocache...}-tags
$params['results'] = preg_replace('!((\{nocache\:([0-9a-f]{32})#(\d+)\})'
.'.*'
.'{/nocache\:\\3#\\4\})!Us'
,'\\2'
,$params['results']);
$this->_cache_info['cache_serials'] = $this->_cache_serials;
// prepend the cache header info into cache file // prepend the cache header info into cache file
$params['results'] = serialize($this->_cache_info)."\n".$params['results']; $params['results'] = serialize($this->_cache_info)."\n".$params['results'];
@@ -54,7 +62,7 @@ function smarty_core_write_cache_file($params, &$this)
$_cache_file = $this->_get_auto_filename($this->cache_dir, $params['tpl_file'], $_auto_id); $_cache_file = $this->_get_auto_filename($this->cache_dir, $params['tpl_file'], $_auto_id);
$_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true); $_params = array('filename' => $_cache_file, 'contents' => $params['results'], 'create_dirs' => true);
require_once(SMARTY_DIR . 'core/core.write_file.php'); require_once(SMARTY_DIR . 'core/core.write_file.php');
smarty_core_write_file($_params, $this); smarty_core_write_file($_params, $this);
return true; return true;
} }
} }

View File

@@ -0,0 +1,60 @@
<?php
/**
* Smarty plugin
* @package Smarty
* @subpackage plugins
*/
/**
* Extract non-cacheable parts out of compiled template and write it
*
* @param string $compile_path
* @param string $template_compiled
* @param integer $template_timestamp
* @return boolean
*/
function smarty_core_write_compiled_include($params, &$this)
{
$_tag_start = 'if \(\$this->caching\) \{ echo \'\{nocache\:('.$this->_cache_serial.')#(\d+)\}\';\}';
$_tag_end = 'if \(\$this->caching\) \{ echo \'\{/nocache\:(\\2)#(\\3)\}\';\}';
preg_match_all('!('.$_tag_start.'(.*)'.$_tag_end.')!Us',
$params['file_compiled'], $_match_source, PREG_SET_ORDER);
// no nocache-parts found: done
if (count($_match_source)==0) return;
// convert the matched php-code to functions
$_include_compiled = "<?php /* funky header here */\n\n";
$_compile_path = $params['include_file_path'];
$this->_cache_serials[$_compile_path] = $this->_cache_serial;
$_include_compiled .= "\$this->_cache_serials['".$_compile_path."'] = '".$this->_cache_serial."';\n\n?>";
$_include_compiled .= $params['plugins_code'];
$_include_compiled .= "<?";
for ($_i = 0, $_for_max = count($_match_source); $_i < $_for_max; $_i++) {
$_match =& $_match_source[$_i];
$_include_compiled .= "
function _smarty_tplfunc_$_match[2]_$_match[3](&\$this)
{
$_match[4]
}
";
}
$_include_compiled .= "\n\n?>\n";
$_params = array('filename' => $_compile_path,
'contents' => $_include_compiled, 'create_dirs' => true);
require_once(SMARTY_DIR . 'core/core.write_file.php');
smarty_core_write_file($_params, $this);
return true;
}
?>