diff --git a/change_log.txt b/change_log.txt index 27932136..07c3890c 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,7 +1,8 @@  ===== 3.1.28-dev===== (xx.xx.2015) 24.10.2015 - more optimizations of template processing - + - bugfix Error when using {include} within {capture} https://github.com/smarty-php/smarty/issues/100 + 21.10.2015 - move some code into runtime extensions diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index 3ad655ff..5746b665 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -123,7 +123,7 @@ class Smarty extends Smarty_Internal_TemplateBase /** * smarty version */ - const SMARTY_VERSION = '3.1.28-dev/72'; + const SMARTY_VERSION = '3.1.28-dev/73'; /** * define variable scopes diff --git a/libs/sysplugins/smarty_internal_extension_handler.php b/libs/sysplugins/smarty_internal_extension_handler.php index 5d2dd782..14e359c9 100644 --- a/libs/sysplugins/smarty_internal_extension_handler.php +++ b/libs/sysplugins/smarty_internal_extension_handler.php @@ -23,6 +23,10 @@ * @property Smarty_Internal_Runtime_CodeFrame $_codeFrame * @property Smarty_Internal_Runtime_FilterHandler $_filterHandler * @property Smarty_Internal_Runtime_GetIncludePath $_getIncludePath + * @property Smarty_Internal_Runtime_Source $_source + * @property Smarty_Internal_Runtime_IsCached $_isCached + * @property Smarty_Internal_Runtime_CacheModify $_cacheModify + * @property Smarty_Internal_Runtime_UpdateCache $_updateCache * @property Smarty_Internal_Method_GetTemplateVars $getTemplateVars * @property Smarty_Internal_Method_Append $append * @property Smarty_Internal_Method_AppendByRef $appendByRef diff --git a/libs/sysplugins/smarty_internal_runtime_cachemodify.php b/libs/sysplugins/smarty_internal_runtime_cachemodify.php new file mode 100644 index 00000000..4e2fb83e --- /dev/null +++ b/libs/sysplugins/smarty_internal_runtime_cachemodify.php @@ -0,0 +1,67 @@ +isCached() && !$_template->compiled->has_nocache_code; + $_last_modified_date = + @substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); + if ($_isCached && $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: + if ( /* ^phpunit */ + !empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS']) /* phpunit$ */ + ) { + $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = '304 Not Modified'; + } else { + 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', $cached->timestamp) . ' GMT'; + } + break; + default: + header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $cached->timestamp) . ' GMT'); + break; + } + echo $content; + } + } +} diff --git a/libs/sysplugins/smarty_internal_runtime_updatecache.php b/libs/sysplugins/smarty_internal_runtime_updatecache.php new file mode 100644 index 00000000..73de954f --- /dev/null +++ b/libs/sysplugins/smarty_internal_runtime_updatecache.php @@ -0,0 +1,184 @@ +hashes[$_template->compiled->nocache_hash]); + if (!empty($cached->hashes)) { + $hash_array = array(); + foreach ($cached->hashes as $hash => $foo) { + $hash_array[] = "/{$hash}/"; + } + $content = preg_replace($hash_array, $_template->compiled->nocache_hash, $content); + } + $_template->cached->has_nocache_code = false; + // get text between non-cached items + $cache_split = + preg_split("!/\*%%SmartyNocache:{$_template->compiled->nocache_hash}%%\*\/(.+?)/\*/%%SmartyNocache:{$_template->compiled->nocache_hash}%%\*/!s", + $content); + // get non-cached items + preg_match_all("!/\*%%SmartyNocache:{$_template->compiled->nocache_hash}%%\*\/(.+?)/\*/%%SmartyNocache:{$_template->compiled->nocache_hash}%%\*/!s", + $content, $cache_parts); + $content = ''; + // loop over items, stitch back together + foreach ($cache_split as $curr_idx => $curr_split) { + // escape PHP tags in template content + $content .= preg_replace('/(<%|%>|<\?php|<\?|\?>|)/', + "\n", $curr_split); + if (isset($cache_parts[0][$curr_idx])) { + $_template->cached->has_nocache_code = true; + $content .= $cache_parts[1][$curr_idx]; + } + } + if (!$no_output_filter && !$_template->compiled->has_nocache_code && + (isset($_template->smarty->autoload_filters['output']) || + isset($_template->smarty->registered_filters['output'])) + ) { + $content = $_template->smarty->ext->_filterHandler->runFilter('output', $content, $_template); + } + // write cache file content + $this->writeCachedContent($cached, $_template, $content); + } + + /** + * Cache was invalid , so render from compiled and write to cache + * + * @param \Smarty_Template_Cached $cached + * @param \Smarty_Internal_Template $_template + * @param $no_output_filter + * + * @throws \Exception + */ + public function updateCache(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template, $no_output_filter) + { + if ($_template->source->handler->uncompiled) { + ob_start(); + $_template->source->render($_template); + } else { + ob_start(); + if (!isset($_template->compiled)) { + $_template->loadCompiled(); + } + $_template->compiled->render($_template); + } + if ($_template->smarty->debugging) { + $_template->smarty->_debug->start_cache($_template); + } + $this->removeNoCacheHash($cached, $_template, $no_output_filter); + $compile_check = $_template->smarty->compile_check; + $_template->smarty->compile_check = false; + if (isset($_template->parent) && $_template->parent->_objType == 2) { + $_template->compiled->unifunc = $_template->parent->compiled->unifunc; + } + if (!$_template->cached->processed) { + $_template->cached->process($_template, true); + } + $_template->smarty->compile_check = $compile_check; + $cached->getRenderedTemplateCode($_template); + if ($_template->smarty->debugging) { + $_template->smarty->_debug->end_cache($_template); + } + } + + /** + * Writes the content to cache resource + * + * @param \Smarty_Template_Cached $cached + * @param Smarty_Internal_Template $_template + * @param string $content + * + * @return bool + */ + public function writeCachedContent(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template, $content) + { + if ($_template->source->handler->recompiled || !($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || + $_template->caching == Smarty::CACHING_LIFETIME_SAVED) + ) { + // don't write cache file + return false; + } + $content = $_template->smarty->ext->_codeFrame->create($_template, $content, '', true); + if (!empty($_template->cached->tpl_function)) { + foreach ($_template->cached->tpl_function as $funcParam) { + if (is_file($funcParam['compiled_filepath'])) { + // read compiled file + $code = file_get_contents($funcParam['compiled_filepath']); + // grab template function + if (preg_match("/\/\* {$funcParam['call_name']} \*\/([\S\s]*?)\/\*\/ {$funcParam['call_name']} \*\//", + $code, $match)) { + unset($code); + $content .= "\n"; + } + } + } + } + return $this->write($cached, $_template, $content); + } + + /** + * Write this cache object to handler + * + * @param \Smarty_Template_Cached $cached + * @param Smarty_Internal_Template $_template template object + * @param string $content content to cache + * + * @return bool success + */ + public function write(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template, $content) + { + if (!$_template->source->handler->recompiled) { + if ($cached->handler->writeCachedContent($_template, $content)) { + $cached->content = null; + $cached->timestamp = time(); + $cached->exists = true; + $cached->valid = true; + $cached->cache_lifetime = $_template->cache_lifetime; + $cached->processed = false; + if ($_template->smarty->cache_locking) { + $cached->handler->releaseLock($_template->smarty, $cached); + } + + return true; + } + $cached->content = null; + $cached->timestamp = false; + $cached->exists = false; + $cached->valid = false; + $cached->processed = false; + } + + return false; + } + +} \ No newline at end of file diff --git a/libs/sysplugins/smarty_internal_template.php b/libs/sysplugins/smarty_internal_template.php index d1314058..ed5e0540 100644 --- a/libs/sysplugins/smarty_internal_template.php +++ b/libs/sysplugins/smarty_internal_template.php @@ -166,7 +166,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase // display or fetch if ($display) { if ($this->caching && $this->smarty->cache_modified_check) { - $this->cached->cacheModifiedCheck($this, isset($content) ? $content : ob_get_clean()); + $this->smarty->ext->_cachemodify->cacheModifiedCheck($this->cached, $this, isset($content) ? $content : ob_get_clean()); } else { if ((!$this->caching || $this->cached->has_nocache_code || $this->source->handler->recompiled) && !$no_output_filter && (isset($this->smarty->autoload_filters['output']) || @@ -187,7 +187,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase } else { if ($this->smarty->debugging) { $this->smarty->_debug->end_template($this); - if ($this->smarty->debugging == 2 and $display === false) { + if ($this->smarty->debugging == 2 and !$display) { $this->smarty->_debug->display_debug($this, true); } } diff --git a/libs/sysplugins/smarty_template_cached.php b/libs/sysplugins/smarty_template_cached.php index 4292ab80..cecf4298 100644 --- a/libs/sysplugins/smarty_template_cached.php +++ b/libs/sysplugins/smarty_template_cached.php @@ -128,32 +128,8 @@ class Smarty_Template_Cached extends Smarty_Template_Resource_Base $_template->smarty->_debug->end_cache($_template); } return; - } elseif ($_template->source->handler->uncompiled) { - ob_start(); - $_template->source->render($_template); } else { - ob_start(); - if (!isset($_template->compiled)) { - $_template->loadCompiled(); - } - $_template->compiled->render($_template); - } - if ($_template->smarty->debugging) { - $_template->smarty->_debug->start_cache($_template); - } - $_template->cached->updateCache($_template, $no_output_filter); - $compile_check = $_template->smarty->compile_check; - $_template->smarty->compile_check = false; - if (isset($this->parent) && $this->parent->_objType == 2) { - $_template->compiled->unifunc = $_template->parent->compiled->unifunc; - } - if (!$_template->cached->processed) { - $_template->cached->process($_template, true); - } - $_template->smarty->compile_check = $compile_check; - $this->getRenderedTemplateCode($_template); - if ($_template->smarty->debugging) { - $_template->smarty->_debug->end_cache($_template); + $_template->smarty->ext->_updateCache->updateCache($this, $_template, $no_output_filter); } } @@ -253,40 +229,6 @@ class Smarty_Template_Cached extends Smarty_Template_Resource_Base } } - /** - * Write this cache object to handler - * - * @param Smarty_Internal_Template $_template template object - * @param string $content content to cache - * - * @return boolean success - */ - public function write(Smarty_Internal_Template $_template, $content) - { - if (!$_template->source->handler->recompiled) { - if ($this->handler->writeCachedContent($_template, $content)) { - $this->content = null; - $this->timestamp = time(); - $this->exists = true; - $this->valid = true; - $this->cache_lifetime = $_template->cache_lifetime; - $this->processed = false; - if ($_template->smarty->cache_locking) { - $this->handler->releaseLock($_template->smarty, $this); - } - - return true; - } - $this->content = null; - $this->timestamp = false; - $this->exists = false; - $this->valid = false; - $this->processed = false; - } - - return false; - } - /** * Read cache content from handler * @@ -301,141 +243,4 @@ class Smarty_Template_Cached extends Smarty_Template_Resource_Base } return false; } - - /** - * Sanitize content and write it to cache resource - * - * @param Smarty_Internal_Template $_template - * @param bool $no_output_filter - * - * @throws \SmartyException - */ - public function updateCache(Smarty_Internal_Template $_template, $no_output_filter) - { - $content = ob_get_clean(); - unset($this->hashes[$_template->compiled->nocache_hash]); - if (!empty($this->hashes)) { - $hash_array = array(); - foreach ($this->hashes as $hash => $foo) { - $hash_array[] = "/{$hash}/"; - } - $content = preg_replace($hash_array, $_template->compiled->nocache_hash, $content); - } - $_template->cached->has_nocache_code = false; - // get text between non-cached items - $cache_split = - preg_split("!/\*%%SmartyNocache:{$_template->compiled->nocache_hash}%%\*\/(.+?)/\*/%%SmartyNocache:{$_template->compiled->nocache_hash}%%\*/!s", - $content); - // get non-cached items - preg_match_all("!/\*%%SmartyNocache:{$_template->compiled->nocache_hash}%%\*\/(.+?)/\*/%%SmartyNocache:{$_template->compiled->nocache_hash}%%\*/!s", - $content, $cache_parts); - $content = ''; - // loop over items, stitch back together - foreach ($cache_split as $curr_idx => $curr_split) { - // escape PHP tags in template content - $content .= preg_replace('/(<%|%>|<\?php|<\?|\?>|)/', - "\n", $curr_split); - if (isset($cache_parts[0][$curr_idx])) { - $_template->cached->has_nocache_code = true; - $content .= $cache_parts[1][$curr_idx]; - } - } - if (!$no_output_filter && !$_template->compiled->has_nocache_code && - (isset($_template->smarty->autoload_filters['output']) || - isset($_template->smarty->registered_filters['output'])) - ) { - $content = $_template->smarty->ext->_filterHandler->runFilter('output', $content, $_template); - } - // write cache file content - $this->writeCachedContent($_template, $content); - } - - /** - * Writes the content to cache resource - * - * @param Smarty_Internal_Template $_template - * @param string $content - * - * @return bool - */ - public function writeCachedContent(Smarty_Internal_Template $_template, $content) - { - if ($_template->source->handler->recompiled || !($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || - $_template->caching == Smarty::CACHING_LIFETIME_SAVED) - ) { - // don't write cache file - return false; - } - $content = $_template->smarty->ext->_codeFrame->create($_template, $content, '', true); - if (!empty($_template->cached->tpl_function)) { - foreach ($_template->cached->tpl_function as $funcParam) { - if (is_file($funcParam['compiled_filepath'])) { - // read compiled file - $code = file_get_contents($funcParam['compiled_filepath']); - // grab template function - if (preg_match("/\/\* {$funcParam['call_name']} \*\/([\S\s]*?)\/\*\/ {$funcParam['call_name']} \*\//", - $code, $match)) { - unset($code); - $content .= "\n"; - } - } - } - } - return $this->write($_template, $content); - } - - /** - * check client side cache - * - * @param Smarty_Internal_Template $_template - * @param string $content - */ - public function cacheModifiedCheck(Smarty_Internal_Template $_template, $content) - { - $_isCached = $_template->isCached() && !$_template->compiled->has_nocache_code; - $_last_modified_date = - @substr($_SERVER['HTTP_IF_MODIFIED_SINCE'], 0, strpos($_SERVER['HTTP_IF_MODIFIED_SINCE'], 'GMT') + 3); - if ($_isCached && $this->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: - if ( /* ^phpunit */ - !empty($_SERVER['SMARTY_PHPUNIT_DISABLE_HEADERS']) /* phpunit$ */ - ) { - $_SERVER['SMARTY_PHPUNIT_HEADERS'][] = '304 Not Modified'; - } else { - 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', $this->timestamp) . ' GMT'; - } - break; - default: - header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $this->timestamp) . ' GMT'); - break; - } - echo $content; - } - } }