From a675aaf68ec4d8eca972462844fb0d7a286f50f8 Mon Sep 17 00:00:00 2001 From: Uwe Tews Date: Thu, 26 Oct 2017 04:37:17 +0200 Subject: [PATCH] - optimization replace internal Smarty::$ds property by DIRECTORY_SEPARATOR (reverted from commit f7a53162058de410a35a9848e6d0795d7c252aaf) (reverted from commit beaa293eb3722138717c9b86047b1805a37c45e0) --- change_log.txt | 4 + libs/Smarty.class.php | 28 +- .../smarty_internal_cacheresource_file.php | 22 +- .../smarty_internal_compile_include_php.php | 8 +- .../smarty_internal_compile_insert.php | 14 +- ...ty_internal_method_compilealltemplates.php | 21 +- .../smarty_internal_resource_file.php | 64 ++-- ...rty_internal_runtime_cacheresourcefile.php | 13 +- ...smarty_internal_runtime_getincludepath.php | 2 +- .../smarty_internal_runtime_writefile.php | 29 +- libs/sysplugins/smarty_resource.php | 327 +++++++++--------- libs/sysplugins/smarty_template_compiled.php | 111 +++--- 12 files changed, 320 insertions(+), 323 deletions(-) diff --git a/change_log.txt b/change_log.txt index 982085f6..08189b93 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,4 +1,8 @@ ===== 3.1.32 - dev === +22.10.2017 3.1.32-dev-28 + - bugfix Smarty version was not filled in header comment of compiled and cached files + - optimization replace internal Smarty::$ds property by DIRECTORY_SEPARATOR + 21.10.2017 - bugfix custom delimiters could fail since modification of version 3.1.32-dev-23 https://github.com/smarty-php/smarty/issues/394 diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index e357bf27..c69715ea 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -100,7 +100,7 @@ class Smarty extends Smarty_Internal_TemplateBase /** * smarty version */ - const SMARTY_VERSION = '3.1.32-dev-27'; + const SMARTY_VERSION = '3.1.32-dev-28'; /** * define variable scopes */ @@ -544,12 +544,6 @@ class Smarty extends Smarty_Internal_TemplateBase * @var Smarty_Internal_Debug */ public $_debug = null; - /** - * Directory separator - * - * @var string - */ - public $ds = DIRECTORY_SEPARATOR; /** * template directory * @@ -942,7 +936,7 @@ class Smarty extends Smarty_Internal_TemplateBase $this->plugins_dir = (array)$this->plugins_dir; } foreach ($this->plugins_dir as $k => $v) { - $this->plugins_dir[ $k ] = $this->_realpath(rtrim($v, "/\\") . $this->ds, true); + $this->plugins_dir[ $k ] = $this->_realpath(rtrim($v, "/\\") . DIRECTORY_SEPARATOR, true); } $this->_cache[ 'plugin_files' ] = array(); $this->_pluginsDirNormalized = true; @@ -1133,9 +1127,9 @@ class Smarty extends Smarty_Internal_TemplateBase */ public function _realpath($path, $realpath = null) { - $nds = $this->ds == '/' ? '\\' : '/'; - // normalize $this->ds - $path = str_replace($nds, $this->ds, $path); + $nds = DIRECTORY_SEPARATOR === '/' ? '\\' : '/'; + // normalize DIRECTORY_SEPARATOR + $path = str_replace($nds, DIRECTORY_SEPARATOR, $path); preg_match('%^(?(?:[[:alpha:]]:[\\\\]|/|[\\\\]{2}[[:alpha:]]+|[[:print:]]{2,}:[/]{2}|[\\\\])?)(?(.*))$%u', $path, $parts); @@ -1144,13 +1138,13 @@ class Smarty extends Smarty_Internal_TemplateBase $parts[ 'root' ] = substr(getcwd(), 0, 2) . $parts[ 'root' ]; } else { if ($realpath !== null && !$parts[ 'root' ]) { - $path = getcwd() . $this->ds . $path; + $path = getcwd() . DIRECTORY_SEPARATOR . $path; } } // remove noop 'DIRECTORY_SEPARATOR DIRECTORY_SEPARATOR' and 'DIRECTORY_SEPARATOR.DIRECTORY_SEPARATOR' patterns - $path = preg_replace('#([\\\\/]([.]?[\\\\/])+)#u', $this->ds, $path); + $path = preg_replace('#([\\\\/]([.]?[\\\\/])+)#u', DIRECTORY_SEPARATOR, $path); // resolve '..DIRECTORY_SEPARATOR' pattern, smallest first - if (strpos($path, '..' . $this->ds) != false && + if (strpos($path, '..' . DIRECTORY_SEPARATOR) != false && preg_match_all('#(([.]?[\\\\/])*([.][.])[\\\\/]([.]?[\\\\/])*)+#u', $path, $match) ) { $counts = array(); @@ -1161,7 +1155,7 @@ class Smarty extends Smarty_Internal_TemplateBase foreach ($counts as $count) { $path = preg_replace('#(([\\\\/]([.]?[\\\\/])*[^\\\\/.]+){' . $count . '}[\\\\/]([.]?[\\\\/])*([.][.][\\\\/]([.]?[\\\\/])*){' . $count . '})(?=[^.])#u', - $this->ds, + DIRECTORY_SEPARATOR, $path); } } @@ -1407,7 +1401,7 @@ class Smarty extends Smarty_Internal_TemplateBase */ private function _normalizeDir($dirName, $dir) { - $this->{$dirName} = $this->_realpath(rtrim($dir, "/\\") . $this->ds, true); + $this->{$dirName} = $this->_realpath(rtrim($dir, "/\\") . DIRECTORY_SEPARATOR, true); if (!isset(Smarty::$_muted_directories[ $this->{$dirName} ])) { Smarty::$_muted_directories[ $this->{$dirName} ] = null; } @@ -1433,7 +1427,7 @@ class Smarty extends Smarty_Internal_TemplateBase } foreach ($dir as $k => $v) { if (!isset($processed[ $k ])) { - $dir[ $k ] = $v = $this->_realpath(rtrim($v, "/\\") . $this->ds, true); + $dir[ $k ] = $v = $this->_realpath(rtrim($v, "/\\") . DIRECTORY_SEPARATOR, true); $processed[ $k ] = true; } } diff --git a/libs/sysplugins/smarty_internal_cacheresource_file.php b/libs/sysplugins/smarty_internal_cacheresource_file.php index 5eb99fb1..7abf6c05 100644 --- a/libs/sysplugins/smarty_internal_cacheresource_file.php +++ b/libs/sysplugins/smarty_internal_cacheresource_file.php @@ -29,13 +29,14 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource { $source = &$_template->source; $smarty = &$_template->smarty; - $_compile_dir_sep = $smarty->use_sub_dirs ? $smarty->ds : '^'; + $_compile_dir_sep = $smarty->use_sub_dirs ? DIRECTORY_SEPARATOR : '^'; $_filepath = sha1($source->uid . $smarty->_joined_template_dir); $cached->filepath = $smarty->getCacheDir(); if (isset($_template->cache_id)) { $cached->filepath .= preg_replace(array('![^\w|]+!', - '![|]+!'), array('_', - $_compile_dir_sep), + '![|]+!'), + array('_', + $_compile_dir_sep), $_template->cache_id) . $_compile_dir_sep; } if (isset($_template->compile_id)) { @@ -43,9 +44,10 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource } // if use_sub_dirs, break file into directories if ($smarty->use_sub_dirs) { - $cached->filepath .= $_filepath[ 0 ] . $_filepath[ 1 ] . $smarty->ds . $_filepath[ 2 ] . $_filepath[ 3 ] . - $smarty->ds . - $_filepath[ 4 ] . $_filepath[ 5 ] . $smarty->ds; + $cached->filepath .= $_filepath[ 0 ] . $_filepath[ 1 ] . DIRECTORY_SEPARATOR . $_filepath[ 2 ] . + $_filepath[ 3 ] . + DIRECTORY_SEPARATOR . + $_filepath[ 4 ] . $_filepath[ 5 ] . DIRECTORY_SEPARATOR; } $cached->filepath .= $_filepath; $basename = $source->handler->getBasename($source); @@ -86,7 +88,8 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource * * @return boolean true or false if the cached content does not exist */ - public function process(Smarty_Internal_Template $_smarty_tpl, Smarty_Template_Cached $cached = null, + public function process(Smarty_Internal_Template $_smarty_tpl, + Smarty_Template_Cached $cached = null, $update = false) { $_smarty_tpl->cached->valid = false; @@ -108,14 +111,15 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource */ public function writeCachedContent(Smarty_Internal_Template $_template, $content) { - if ($_template->smarty->ext->_writeFile->writeFile($_template->cached->filepath, $content, + if ($_template->smarty->ext->_writeFile->writeFile($_template->cached->filepath, + $content, $_template->smarty) === true ) { if (function_exists('opcache_invalidate') && (!function_exists('ini_get') || strlen(ini_get("opcache.restrict_api"))) < 1 ) { opcache_invalidate($_template->cached->filepath, true); - } elseif (function_exists('apc_compile_file')) { + } else if (function_exists('apc_compile_file')) { apc_compile_file($_template->cached->filepath); } $cached = $_template->cached; diff --git a/libs/sysplugins/smarty_internal_compile_include_php.php b/libs/sysplugins/smarty_internal_compile_include_php.php index 77586da8..a799ea59 100644 --- a/libs/sysplugins/smarty_internal_compile_include_php.php +++ b/libs/sysplugins/smarty_internal_compile_include_php.php @@ -57,7 +57,6 @@ class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase } // check and get attributes $_attr = $this->getAttributes($compiler, $args); - /** @var Smarty_Internal_Template $_smarty_tpl * used in evaluated code */ @@ -74,8 +73,8 @@ class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase $_dir = $compiler->smarty->trusted_dir; } if (!empty($_dir)) { - foreach ((array) $_dir as $_script_dir) { - $_path = $compiler->smarty->_realpath($_script_dir . $compiler->smarty->ds . $_file, true); + foreach ((array)$_dir as $_script_dir) { + $_path = $compiler->smarty->_realpath($_script_dir . DIRECTORY_SEPARATOR . $_file, true); if (file_exists($_path)) { $_filepath = $_path; break; @@ -86,11 +85,9 @@ class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase if ($_filepath == false) { $compiler->trigger_template_error("{include_php} file '{$_file}' is not readable", null, true); } - if (isset($compiler->smarty->security_policy)) { $compiler->smarty->security_policy->isTrustedPHPDir($_filepath); } - if (isset($_attr[ 'assign' ])) { // output will be stored in a smarty variable instead of being displayed $_assign = $_attr[ 'assign' ]; @@ -101,7 +98,6 @@ class Smarty_Internal_Compile_Include_Php extends Smarty_Internal_CompileBase $_once = ''; } } - if (isset($_assign)) { return "assign({$_assign},ob_get_clean());\n?>"; } else { diff --git a/libs/sysplugins/smarty_internal_compile_insert.php b/libs/sysplugins/smarty_internal_compile_insert.php index 02ef67c3..a72db298 100644 --- a/libs/sysplugins/smarty_internal_compile_insert.php +++ b/libs/sysplugins/smarty_internal_compile_insert.php @@ -1,5 +1,4 @@ getAttributes($compiler, $args); //Does tag create output $compiler->has_output = isset($_attr[ 'assign' ]) ? false : true; - $nocacheParam = $compiler->template->caching && ($compiler->tag_nocache || $compiler->nocache); if (!$nocacheParam) { // do not compile as nocache code @@ -66,7 +64,6 @@ class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase $_smarty_tpl = $compiler->template; $_name = null; $_script = null; - $_output = 'smarty instanceof SmartyBC ? $compiler->smarty->trusted_dir : null; } if (!empty($_dir)) { - foreach ((array) $_dir as $_script_dir) { - $_script_dir = rtrim($_script_dir, '/\\') . $compiler->smarty->ds; + foreach ((array)$_dir as $_script_dir) { + $_script_dir = rtrim($_script_dir, '/\\') . DIRECTORY_SEPARATOR; if (file_exists($_script_dir . $_script)) { $_filepath = $_script_dir . $_script; break; @@ -113,7 +110,8 @@ class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase require_once $_filepath; if (!is_callable($_function)) { $compiler->trigger_template_error(" {insert} function '{$_function}' is not callable in script file '{$_script}'", - null, true); + null, + true); } } else { $_filepath = 'null'; @@ -122,7 +120,8 @@ class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase if (!is_callable($_function)) { // try plugin if (!$_function = $compiler->getPlugin($_name, 'insert')) { - $compiler->trigger_template_error("{insert} no function or plugin found for '{$_name}'", null, + $compiler->trigger_template_error("{insert} no function or plugin found for '{$_name}'", + null, true); } } @@ -149,7 +148,6 @@ class Smarty_Internal_Compile_Insert extends Smarty_Internal_CompileBase $_output .= "echo {$_function}({$_params},\$_smarty_tpl);?>"; } } - return $_output; } } diff --git a/libs/sysplugins/smarty_internal_method_compilealltemplates.php b/libs/sysplugins/smarty_internal_method_compilealltemplates.php index 0abed212..d19fbeef 100644 --- a/libs/sysplugins/smarty_internal_method_compilealltemplates.php +++ b/libs/sysplugins/smarty_internal_method_compilealltemplates.php @@ -31,7 +31,10 @@ class Smarty_Internal_Method_CompileAllTemplates * * @return integer number of template files recompiled */ - public function compileAllTemplates(Smarty $smarty, $extension = '.tpl', $force_compile = false, $time_limit = 0, + public function compileAllTemplates(Smarty $smarty, + $extension = '.tpl', + $force_compile = false, + $time_limit = 0, $max_errors = null) { return $this->compileAll($smarty, $extension, $force_compile, $time_limit, $max_errors); @@ -49,7 +52,11 @@ class Smarty_Internal_Method_CompileAllTemplates * * @return int number of template files compiled */ - protected function compileAll(Smarty $smarty, $extension, $force_compile, $time_limit, $max_errors, + protected function compileAll(Smarty $smarty, + $extension, + $force_compile, + $time_limit, + $max_errors, $isConfig = false) { // switch off time limit @@ -69,11 +76,11 @@ class Smarty_Internal_Method_CompileAllTemplates if (substr(basename($_fileinfo->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false) { continue; } - if (!substr_compare($_file, $extension, - strlen($extension)) == 0) { + if (!substr_compare($_file, $extension, -strlen($extension)) == 0) { continue; } - if ($_fileinfo->getPath() !== substr($_dir, 0, - 1)) { - $_file = substr($_fileinfo->getPath(), strlen($_dir)) . $smarty->ds . $_file; + if ($_fileinfo->getPath() !== substr($_dir, 0, -1)) { + $_file = substr($_fileinfo->getPath(), strlen($_dir)) . DIRECTORY_SEPARATOR . $_file; } echo "\n
", $_dir, '---', $_file; flush(); @@ -92,7 +99,7 @@ class Smarty_Internal_Method_CompileAllTemplates $isConfig ? Smarty_Template_Config::load($_tpl) : Smarty_Template_Source::load($_tpl); if ($_tpl->mustCompile()) { $_tpl->compileTemplateSource(); - $_count ++; + $_count++; echo ' compiled in ', microtime(true) - $_start_time, ' seconds'; flush(); } else { @@ -102,7 +109,7 @@ class Smarty_Internal_Method_CompileAllTemplates } catch (Exception $e) { echo "\n
------>Error: ", $e->getMessage(), "

\n"; - $_error_count ++; + $_error_count++; } // free memory unset($_tpl); diff --git a/libs/sysplugins/smarty_internal_resource_file.php b/libs/sysplugins/smarty_internal_resource_file.php index a58771a1..0f8c2478 100644 --- a/libs/sysplugins/smarty_internal_resource_file.php +++ b/libs/sysplugins/smarty_internal_resource_file.php @@ -17,6 +17,30 @@ */ class Smarty_Internal_Resource_File extends Smarty_Resource { + /** + * populate Source Object with meta data from Resource + * + * @param Smarty_Template_Source $source source object + * @param Smarty_Internal_Template $_template template object + * + * @throws \SmartyException + */ + public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null) + { + $source->filepath = $this->buildFilepath($source, $_template); + if ($source->filepath !== false) { + if (isset($source->smarty->security_policy) && is_object($source->smarty->security_policy)) { + $source->smarty->security_policy->isTrustedResourceDir($source->filepath, $source->isConfig); + } + $source->exists = true; + $source->uid = sha1($source->filepath . ($source->isConfig ? $source->smarty->_joined_config_dir : + $source->smarty->_joined_template_dir)); + $source->timestamp = filemtime($source->filepath); + } else { + $source->timestamp = $source->exists = false; + } + } + /** * build template filepath by traversing the template_dir array * @@ -44,15 +68,15 @@ class Smarty_Internal_Resource_File extends Smarty_Resource throw new SmartyException("Template '{$file}' cannot be relative to template of resource type '{$_template->parent->source->type}'"); } // normalize path - $path = $source->smarty->_realpath(dirname($_template->parent->source->filepath) . $source->smarty->ds . $file); + $path = + $source->smarty->_realpath(dirname($_template->parent->source->filepath) . DIRECTORY_SEPARATOR . $file); // files relative to a template only get one shot return is_file($path) ? $path : false; } - // normalize $source->smarty->ds - if (strpos($file, $source->smarty->ds == '/' ? '\\' : '/') !== false) { - $file = str_replace($source->smarty->ds == '/' ? '\\' : '/', $source->smarty->ds, $file); + // normalize DIRECTORY_SEPARATOR + if (strpos($file, DIRECTORY_SEPARATOR === '/' ? '\\' : '/') !== false) { + $file = str_replace(DIRECTORY_SEPARATOR === '/' ? '\\' : '/', DIRECTORY_SEPARATOR, $file); } - $_directories = $source->smarty->getTemplateDir(null, $source->isConfig); // template_dir index? if ($file[ 0 ] == '[' && preg_match('#^\[([^\]]+)\](.+)$#', $file, $fileMatch)) { @@ -64,9 +88,9 @@ class Smarty_Internal_Resource_File extends Smarty_Resource // try string indexes if (isset($_directories[ $index ])) { $_index_dirs[] = $_directories[ $index ]; - } elseif (is_numeric($index)) { + } else if (is_numeric($index)) { // try numeric index - $index = (int) $index; + $index = (int)$index; if (isset($_directories[ $index ])) { $_index_dirs[] = $_directories[ $index ]; } else { @@ -85,12 +109,11 @@ class Smarty_Internal_Resource_File extends Smarty_Resource $_directories = $_index_dirs; } } - // relative file name? foreach ($_directories as $_directory) { $path = $_directory . $file; if (is_file($path)) { - return (strpos($path, '.' . $source->smarty->ds) !== false) ? $source->smarty->_realpath($path) : $path; + return (strpos($path, '.' . DIRECTORY_SEPARATOR) !== false) ? $source->smarty->_realpath($path) : $path; } } if (!isset($_index_dirs)) { @@ -107,29 +130,6 @@ class Smarty_Internal_Resource_File extends Smarty_Resource return false; } - /** - * populate Source Object with meta data from Resource - * - * @param Smarty_Template_Source $source source object - * @param Smarty_Internal_Template $_template template object - */ - public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template = null) - { - $source->filepath = $this->buildFilepath($source, $_template); - - if ($source->filepath !== false) { - if (isset($source->smarty->security_policy) && is_object($source->smarty->security_policy)) { - $source->smarty->security_policy->isTrustedResourceDir($source->filepath, $source->isConfig); - } - $source->exists = true; - $source->uid = sha1($source->filepath . ($source->isConfig ? $source->smarty->_joined_config_dir : - $source->smarty->_joined_template_dir)); - $source->timestamp = filemtime($source->filepath); - } else { - $source->timestamp = $source->exists = false; - } - } - /** * populate Source Object with timestamp and exists from Resource * diff --git a/libs/sysplugins/smarty_internal_runtime_cacheresourcefile.php b/libs/sysplugins/smarty_internal_runtime_cacheresourcefile.php index 38ad41cb..801aa300 100644 --- a/libs/sysplugins/smarty_internal_runtime_cacheresourcefile.php +++ b/libs/sysplugins/smarty_internal_runtime_cacheresourcefile.php @@ -1,5 +1,4 @@ use_sub_dirs) { foreach ($_cache_id_parts as $id_part) { - $_dir .= $id_part . $smarty->ds; + $_dir .= $id_part . DIRECTORY_SEPARATOR; } } } @@ -52,10 +51,8 @@ class Smarty_Internal_Runtime_CacheResourceFile $smarty->caching = true; $tpl = new $smarty->template_class($resource_name, $smarty); $smarty->caching = $_save_stat; - // remove from template cache $tpl->source; // have the template registered before unset() - if ($tpl->source->exists) { $_resourcename_parts = basename(str_replace('^', '/', $tpl->cached->filepath)); } else { @@ -71,7 +68,7 @@ class Smarty_Internal_Runtime_CacheResourceFile if (substr(basename($_file->getPathname()), 0, 1) == '.') { continue; } - $_filepath = (string) $_file; + $_filepath = (string)$_file; // directory ? if ($_file->isDir()) { if (!$_cache->isDot()) { @@ -80,7 +77,7 @@ class Smarty_Internal_Runtime_CacheResourceFile } } else { // delete only php files - if (substr($_filepath, - 4) !== '.php') { + if (substr($_filepath, -4) !== '.php') { continue; } $_parts = explode($_dir_sep, str_replace('\\', '/', substr($_filepath, $_dir_length))); @@ -105,7 +102,7 @@ class Smarty_Internal_Runtime_CacheResourceFile if ($_parts_count < $_cache_id_parts_count) { continue; } - for ($i = 0; $i < $_cache_id_parts_count; $i ++) { + for ($i = 0; $i < $_cache_id_parts_count; $i++) { if ($_parts[ $i ] != $_cache_id_parts[ $i ]) { continue 2; } @@ -130,7 +127,7 @@ class Smarty_Internal_Runtime_CacheResourceFile && (!function_exists('ini_get') || strlen(ini_get("opcache.restrict_api")) < 1) ) { opcache_invalidate($_filepath, true); - } elseif (function_exists('apc_delete_file')) { + } else if (function_exists('apc_delete_file')) { apc_delete_file($_filepath); } } diff --git a/libs/sysplugins/smarty_internal_runtime_getincludepath.php b/libs/sysplugins/smarty_internal_runtime_getincludepath.php index e12b0c57..967c937a 100644 --- a/libs/sysplugins/smarty_internal_runtime_getincludepath.php +++ b/libs/sysplugins/smarty_internal_runtime_getincludepath.php @@ -87,7 +87,7 @@ class Smarty_Internal_Runtime_GetIncludePath $_dirs = (array) explode(PATH_SEPARATOR, $_i_path); foreach ($_dirs as $_path) { if (is_dir($_path)) { - $this->_include_dirs[] = $smarty->_realpath($_path . $smarty->ds, true); + $this->_include_dirs[] = $smarty->_realpath($_path . DIRECTORY_SEPARATOR, true); } } return true; diff --git a/libs/sysplugins/smarty_internal_runtime_writefile.php b/libs/sysplugins/smarty_internal_runtime_writefile.php index ffa0b51e..d9206683 100644 --- a/libs/sysplugins/smarty_internal_runtime_writefile.php +++ b/libs/sysplugins/smarty_internal_runtime_writefile.php @@ -35,34 +35,30 @@ class Smarty_Internal_Runtime_WriteFile if ($_file_perms !== null) { $old_umask = umask(0); } - $_dirpath = dirname($_filepath); - - // if subdirs, create dir structure + // if subdirs, create dir structure if ($_dirpath !== '.') { - $i=0; + $i = 0; // loop if concurrency problem occurs // see https://bugs.php.net/bug.php?id=35326 while (!is_dir($_dirpath)) { - if (@mkdir($_dirpath, $_dir_perms, true)) { - break; - } - clearstatcache(); - if (++$i === 3) { - error_reporting($_error_reporting); - throw new SmartyException("unable to create directory {$_dirpath}"); - } - sleep(1); + if (@mkdir($_dirpath, $_dir_perms, true)) { + break; + } + clearstatcache(); + if (++$i === 3) { + error_reporting($_error_reporting); + throw new SmartyException("unable to create directory {$_dirpath}"); + } + sleep(1); } } - // write to tmp file, then move to overt file lock race condition - $_tmp_file = $_dirpath . $smarty->ds . str_replace(array('.', ','), '_', uniqid('wrt', true)); + $_tmp_file = $_dirpath . DIRECTORY_SEPARATOR . str_replace(array('.', ','), '_', uniqid('wrt', true)); if (!file_put_contents($_tmp_file, $_contents)) { error_reporting($_error_reporting); throw new SmartyException("unable to write file {$_tmp_file}"); } - /* * Windows' rename() fails if the destination exists, * Linux' rename() properly handles the overwrite. @@ -99,7 +95,6 @@ class Smarty_Internal_Runtime_WriteFile umask($old_umask); } error_reporting($_error_reporting); - return true; } } diff --git a/libs/sysplugins/smarty_resource.php b/libs/sysplugins/smarty_resource.php index ea673ead..295c08a1 100644 --- a/libs/sysplugins/smarty_resource.php +++ b/libs/sysplugins/smarty_resource.php @@ -14,12 +14,22 @@ * @package Smarty * @subpackage TemplateResources * - * @method renderUncompiled(Smarty_Template_Source $source, Smarty_Internal_Template $_template) - * @method populateCompiledFilepath(Smarty_Template_Compiled $compiled, Smarty_Internal_Template $_template) * @method process(Smarty_Internal_Template $_smarty_tpl) */ abstract class Smarty_Resource { + /** + * resource types provided by the core + * + * @var array + */ + public static $sysplugins = array('file' => 'smarty_internal_resource_file.php', + 'string' => 'smarty_internal_resource_string.php', + 'extends' => 'smarty_internal_resource_extends.php', + 'stream' => 'smarty_internal_resource_stream.php', + 'eval' => 'smarty_internal_resource_eval.php', + 'php' => 'smarty_internal_resource_php.php'); + /** * Source is bypassing compiler * @@ -34,18 +44,6 @@ abstract class Smarty_Resource */ public $recompiled = false; - /** - * resource types provided by the core - * - * @var array - */ - public static $sysplugins = array('file' => 'smarty_internal_resource_file.php', - 'string' => 'smarty_internal_resource_string.php', - 'extends' => 'smarty_internal_resource_extends.php', - 'stream' => 'smarty_internal_resource_stream.php', - 'eval' => 'smarty_internal_resource_eval.php', - 'php' => 'smarty_internal_resource_php.php'); - /** * Flag if resource does implement populateCompiledFilepath() method * @@ -53,6 +51,152 @@ abstract class Smarty_Resource */ public $hasCompiledHandler = false; + /** + * modify template_resource according to resource handlers specifications + * + * @param \Smarty_Internal_Template|\Smarty $obj Smarty instance + * @param string $template_resource template_resource to extract resource handler and name of + * + * @return string unique resource name + * @throws \SmartyException + */ + public static function getUniqueTemplateName($obj, $template_resource) + { + $smarty = $obj->_getSmartyObj(); + list($name, $type) = self::parseResourceName($template_resource, $smarty->default_resource_type); + // TODO: optimize for Smarty's internal resource types + $resource = Smarty_Resource::load($smarty, $type); + // go relative to a given template? + $_file_is_dotted = $name[ 0 ] == '.' && ($name[ 1 ] == '.' || $name[ 1 ] == '/'); + if ($obj->_isTplObj() && $_file_is_dotted && + ($obj->source->type == 'file' || $obj->parent->source->type == 'extends') + ) { + $name = $smarty->_realpath(dirname($obj->parent->source->filepath) . DIRECTORY_SEPARATOR . $name); + } + return $resource->buildUniqueResourceName($smarty, $name); + } + + /** + * extract resource_type and resource_name from template_resource and config_resource + * @note "C:/foo.tpl" was forced to file resource up till Smarty 3.1.3 (including). + * + * @param string $resource_name template_resource or config_resource to parse + * @param string $default_resource the default resource_type defined in $smarty + * + * @return array with parsed resource name and type + */ + public static function parseResourceName($resource_name, $default_resource) + { + if (preg_match('/^([A-Za-z0-9_\-]{2,})[:]/', $resource_name, $match)) { + $type = $match[ 1 ]; + $name = substr($resource_name, strlen($match[ 0 ])); + } else { + // no resource given, use default + // or single character before the colon is not a resource type, but part of the filepath + $type = $default_resource; + $name = $resource_name; + } + return array($name, $type); + } + + /** + * Load Resource Handler + * + * @param Smarty $smarty smarty object + * @param string $type name of the resource + * + * @throws SmartyException + * @return Smarty_Resource Resource Handler + */ + public static function load(Smarty $smarty, $type) + { + /* @var array \Smarty_Internal_Resource_File|\Smarty_Internal_Resource_Php|\Smarty_Internal_Resource_Extends|\Smarty_Internal_Resource_Eval|\Smarty_Internal_Resource_String|\Smarty_Internal_Resource_Stream|\Smarty_Internal_Resource_Registered */ + static $handlerCache = array(); + // try smarty's cache + if (isset($handlerCache[ $type ])) { + return $handlerCache[ $type ]; + } + // try registered resource + if (isset($smarty->registered_resources[ $type ])) { + return $handlerCache[ $type ] = + $smarty->registered_resources[ $type ] instanceof Smarty_Resource ? + $smarty->registered_resources[ $type ] : new Smarty_Internal_Resource_Registered(); + } + // try sysplugins dir + if (isset(self::$sysplugins[ $type ])) { + $_resource_class = 'Smarty_Internal_Resource_' . ucfirst($type); + return $handlerCache[ $type ] = new $_resource_class(); + } + // try plugins dir + $_resource_class = 'Smarty_Resource_' . ucfirst($type); + if ($smarty->loadPlugin($_resource_class)) { + if (class_exists($_resource_class, false)) { + return $handlerCache[ $type ] = new $_resource_class(); + } else { + $smarty->registerResource($type, + array("smarty_resource_{$type}_source", "smarty_resource_{$type}_timestamp", + "smarty_resource_{$type}_secure", "smarty_resource_{$type}_trusted")); + // give it another try, now that the resource is registered properly + return self::load($smarty, $type); + } + } + // try streams + $_known_stream = stream_get_wrappers(); + if (in_array($type, $_known_stream)) { + // is known stream + if (is_object($smarty->security_policy)) { + $smarty->security_policy->isTrustedStream($type); + } + return $handlerCache[ $type ] = new Smarty_Internal_Resource_Stream(); + } + // TODO: try default_(template|config)_handler + // give up + throw new SmartyException("Unknown resource type '{$type}'"); + } + + /** + * modify resource_name according to resource handlers specifications + * + * @param Smarty $smarty Smarty instance + * @param string $resource_name resource_name to make unique + * @param boolean $isConfig flag for config resource + * + * @return string unique resource name + */ + public function buildUniqueResourceName(Smarty $smarty, $resource_name, $isConfig = false) + { + if ($isConfig) { + if (!isset($smarty->_joined_config_dir)) { + $smarty->getTemplateDir(null, true); + } + return get_class($this) . '#' . $smarty->_joined_config_dir . '#' . $resource_name; + } else { + if (!isset($smarty->_joined_template_dir)) { + $smarty->getTemplateDir(); + } + return get_class($this) . '#' . $smarty->_joined_template_dir . '#' . $resource_name; + } + } + + /** + * initialize Source Object for given resource + * wrapper for backward compatibility to versions < 3.1.22 + * Either [$_template] or [$smarty, $template_resource] must be specified + * + * @param Smarty_Internal_Template $_template template object + * @param Smarty $smarty smarty object + * @param string $template_resource resource identifier + * + * @return \Smarty_Template_Source Source Object + * @throws \SmartyException + */ + public static function source(Smarty_Internal_Template $_template = null, + Smarty $smarty = null, + $template_resource = null) + { + return Smarty_Template_Source::load($_template, $smarty, $template_resource); + } + /** * Load template's source into current template object * @@ -81,30 +225,12 @@ abstract class Smarty_Resource // intentionally left blank } - /** - * modify resource_name according to resource handlers specifications + /* + * Check if resource must check time stamps when when loading complied or cached templates. + * Resources like 'extends' which use source components my disable timestamp checks on own resource. * - * @param Smarty $smarty Smarty instance - * @param string $resource_name resource_name to make unique - * @param boolean $isConfig flag for config resource - * - * @return string unique resource name + * @return bool */ - public function buildUniqueResourceName(Smarty $smarty, $resource_name, $isConfig = false) - { - if ($isConfig) { - if (!isset($smarty->_joined_config_dir)) { - $smarty->getTemplateDir(null, true); - } - return get_class($this) . '#' . $smarty->_joined_config_dir . '#' . $resource_name; - } else { - if (!isset($smarty->_joined_template_dir)) { - $smarty->getTemplateDir(); - } - return get_class($this) . '#' . $smarty->_joined_template_dir . '#' . $resource_name; - } - } - /** * Determine basename for compiled filename * @@ -117,138 +243,9 @@ abstract class Smarty_Resource return basename(preg_replace('![^\w]+!', '_', $source->name)); } - /** - * Load Resource Handler - * - * @param Smarty $smarty smarty object - * @param string $type name of the resource - * - * @throws SmartyException - * @return Smarty_Resource Resource Handler - */ - public static function load(Smarty $smarty, $type) - { - // try smarty's cache - if (isset($smarty->_cache[ 'resource_handlers' ][ $type ])) { - return $smarty->_cache[ 'resource_handlers' ][ $type ]; - } - - // try registered resource - if (isset($smarty->registered_resources[ $type ])) { - return $smarty->_cache[ 'resource_handlers' ][ $type ] = - $smarty->registered_resources[ $type ] instanceof Smarty_Resource ? - $smarty->registered_resources[ $type ] : new Smarty_Internal_Resource_Registered(); - } - - // try sysplugins dir - if (isset(self::$sysplugins[ $type ])) { - $_resource_class = 'Smarty_Internal_Resource_' . ucfirst($type); - return $smarty->_cache[ 'resource_handlers' ][ $type ] = new $_resource_class(); - } - - // try plugins dir - $_resource_class = 'Smarty_Resource_' . ucfirst($type); - if ($smarty->loadPlugin($_resource_class)) { - if (class_exists($_resource_class, false)) { - return $smarty->_cache[ 'resource_handlers' ][ $type ] = new $_resource_class(); - } else { - $smarty->registerResource($type, - array("smarty_resource_{$type}_source", "smarty_resource_{$type}_timestamp", - "smarty_resource_{$type}_secure", "smarty_resource_{$type}_trusted")); - // give it another try, now that the resource is registered properly - return self::load($smarty, $type); - } - } - - // try streams - $_known_stream = stream_get_wrappers(); - if (in_array($type, $_known_stream)) { - // is known stream - if (is_object($smarty->security_policy)) { - $smarty->security_policy->isTrustedStream($type); - } - return $smarty->_cache[ 'resource_handlers' ][ $type ] = new Smarty_Internal_Resource_Stream(); - } - - // TODO: try default_(template|config)_handler - - // give up - throw new SmartyException("Unknown resource type '{$type}'"); - } - - /** - * extract resource_type and resource_name from template_resource and config_resource - * @note "C:/foo.tpl" was forced to file resource up till Smarty 3.1.3 (including). - * - * @param string $resource_name template_resource or config_resource to parse - * @param string $default_resource the default resource_type defined in $smarty - * - * @return array with parsed resource name and type - */ - public static function parseResourceName($resource_name, $default_resource) - { - if (preg_match('/^([A-Za-z0-9_\-]{2,})[:]/', $resource_name, $match)) { - $type = $match[ 1 ]; - $name = substr($resource_name, strlen($match[ 0 ])); - } else { - // no resource given, use default - // or single character before the colon is not a resource type, but part of the filepath - $type = $default_resource; - $name = $resource_name; - } - return array($name, $type); - } - - /** - * modify template_resource according to resource handlers specifications - * - * @param \Smarty_Internal_Template|\Smarty $obj Smarty instance - * @param string $template_resource template_resource to extract resource handler and name of - * - * @return string unique resource name - */ - public static function getUniqueTemplateName($obj, $template_resource) - { - $smarty = $obj->_getSmartyObj(); - list($name, $type) = self::parseResourceName($template_resource, $smarty->default_resource_type); - // TODO: optimize for Smarty's internal resource types - $resource = Smarty_Resource::load($smarty, $type); - // go relative to a given template? - $_file_is_dotted = $name[ 0 ] == '.' && ($name[ 1 ] == '.' || $name[ 1 ] == '/'); - if ($obj->_isTplObj() && $_file_is_dotted && - ($obj->source->type == 'file' || $obj->parent->source->type == 'extends') - ) { - $name = $smarty->_realpath(dirname($obj->parent->source->filepath) . $smarty->ds . $name); - } - return $resource->buildUniqueResourceName($smarty, $name); - } - - /* - * Check if resource must check time stamps when when loading complied or cached templates. - * Resources like 'extends' which use source components my disable timestamp checks on own resource. - * - * @return bool - */ public function checkTimestamps() { return true; } - - /** - * initialize Source Object for given resource - * wrapper for backward compatibility to versions < 3.1.22 - * Either [$_template] or [$smarty, $template_resource] must be specified - * - * @param Smarty_Internal_Template $_template template object - * @param Smarty $smarty smarty object - * @param string $template_resource resource identifier - * - * @return Smarty_Template_Source Source Object - */ - public static function source(Smarty_Internal_Template $_template = null, Smarty $smarty = null, - $template_resource = null) - { - return Smarty_Template_Source::load($_template, $smarty, $template_resource); - } } diff --git a/libs/sysplugins/smarty_template_compiled.php b/libs/sysplugins/smarty_template_compiled.php index 1cd4d297..957b4669 100644 --- a/libs/sysplugins/smarty_template_compiled.php +++ b/libs/sysplugins/smarty_template_compiled.php @@ -7,11 +7,9 @@ * @package Smarty * @subpackage TemplateResources * @author Rodney Rehm - * @property string $content compiled content */ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base { - /** * nocache hash * @@ -22,11 +20,11 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base /** * get a Compiled Object of this source * - * @param Smarty_Internal_Template $_template template object + * @param \Smarty_Internal_Template $_template template object * - * @return Smarty_Template_Compiled compiled object + * @return \Smarty_Template_Compiled compiled object */ - static function load($_template) + static function load(\Smarty_Internal_Template $_template) { $compiled = new Smarty_Template_Compiled(); if ($_template->source->handler->hasCompiledHandler) { @@ -40,30 +38,31 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base /** * populate Compiled Object with compiled filepath * - * @param Smarty_Internal_Template $_template template object + * @param \Smarty_Internal_Template $_template template object **/ - public function populateCompiledFilepath(Smarty_Internal_Template $_template) + public function populateCompiledFilepath(\Smarty_Internal_Template $_template) { $source = &$_template->source; $smarty = &$_template->smarty; $this->filepath = $smarty->getCompileDir(); if (isset($_template->compile_id)) { $this->filepath .= preg_replace('![^\w]+!', '_', $_template->compile_id) . - ($smarty->use_sub_dirs ? $smarty->ds : '^'); + ($smarty->use_sub_dirs ? DIRECTORY_SEPARATOR : '^'); } + $uid = $source->uid; // if use_sub_dirs, break file into directories if ($smarty->use_sub_dirs) { - $this->filepath .= $source->uid[ 0 ] . $source->uid[ 1 ] . $smarty->ds . $source->uid[ 2 ] . - $source->uid[ 3 ] . $smarty->ds . $source->uid[ 4 ] . $source->uid[ 5 ] . $smarty->ds; + $this->filepath .= $uid[ 0 ] . $uid[ 1 ] . DIRECTORY_SEPARATOR . $uid[ 2 ] . + $uid[ 3 ] . DIRECTORY_SEPARATOR . $uid[ 4 ] . $uid[ 5 ] . DIRECTORY_SEPARATOR; } - $this->filepath .= $source->uid . '_'; + $this->filepath .= $uid . '_'; if ($source->isConfig) { - $this->filepath .= (int) $smarty->config_read_hidden + (int) $smarty->config_booleanize * 2 + - (int) $smarty->config_overwrite * 4; + $this->filepath .= (int)$smarty->config_read_hidden + (int)$smarty->config_booleanize * 2 + + (int)$smarty->config_overwrite * 4; } else { - $this->filepath .= (int) $smarty->merge_compiled_includes + (int) $smarty->escape_html * 2 + + $this->filepath .= (int)$smarty->merge_compiled_includes + (int)$smarty->escape_html * 2 + (($smarty->merge_compiled_includes && $source->type === 'extends') ? - (int) $smarty->extends_recursion * 4 : 0); + (int)$smarty->extends_recursion * 4 : 0); } $this->filepath .= '.' . $source->type; $basename = $source->handler->getBasename($source); @@ -74,21 +73,26 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base $this->filepath .= '.cache'; } $this->filepath .= '.php'; - $this->timestamp = $this->exists = is_file($this->filepath); - if ($this->exists) { - $this->timestamp = filemtime($this->filepath); + if ($smarty->force_compile) { + // no need to obtain file status + $this->timestamp = $this->exists = false; + } else { + $this->timestamp = $this->exists = is_file($this->filepath); + if ($this->exists) { + $this->timestamp = filemtime($this->filepath); + } } } /** * render compiled template code * - * @param Smarty_Internal_Template $_template + * @param \Smarty_Internal_Template $_template * * @return string * @throws Exception */ - public function render(Smarty_Internal_Template $_template) + public function render(\Smarty_Internal_Template $_template) { // checks if template exists if (!$_template->source->exists) { @@ -124,17 +128,17 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base /** * load compiled template or compile from source * - * @param Smarty_Internal_Template $_smarty_tpl do not change variable name, is used by compiled template + * @param \Smarty_Internal_Template $_smarty_tpl do not change variable name, is used by compiled template * * @throws Exception */ - public function process(Smarty_Internal_Template $_smarty_tpl) + public function process(\Smarty_Internal_Template $_smarty_tpl) { $source = &$_smarty_tpl->source; $smarty = &$_smarty_tpl->smarty; if ($source->handler->recompiled) { $source->handler->process($_smarty_tpl); - } elseif (!$source->handler->uncompiled) { + } else if (!$source->handler->uncompiled) { if (!$this->exists || $smarty->force_compile || ($smarty->compile_check && $source->getTimeStamp() > $this->getTimeStamp()) ) { @@ -162,11 +166,11 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base /** * compile template from source * - * @param Smarty_Internal_Template $_template + * @param \Smarty_Internal_Template $_template * * @throws Exception */ - public function compileTemplateSource(Smarty_Internal_Template $_template) + public function compileTemplateSource(\Smarty_Internal_Template $_template) { $this->file_dependency = array(); $this->includes = array(); @@ -195,15 +199,38 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base unset($_template->compiler); } + /** + * Load fresh compiled template by including the PHP file + * HHVM requires a work around because of a PHP incompatibility + * + * @param \Smarty_Internal_Template $_smarty_tpl do not change variable name, is used by compiled template + */ + private function loadCompiledTemplate(\Smarty_Internal_Template $_smarty_tpl) + { + if (function_exists('opcache_invalidate') + && (!function_exists('ini_get') || strlen(ini_get("opcache.restrict_api")) < 1) + ) { + opcache_invalidate($this->filepath, true); + } else if (function_exists('apc_compile_file')) { + apc_compile_file($this->filepath); + } + if (defined('HHVM_VERSION')) { + eval("?>" . file_get_contents($this->filepath)); + } else { + include($this->filepath); + } + } + /** * Write compiled code by handler * - * @param Smarty_Internal_Template $_template template object - * @param string $code compiled code + * @param \Smarty_Internal_Template $_template template object + * @param string $code compiled code * - * @return boolean success + * @return bool success + * @throws \SmartyException */ - public function write(Smarty_Internal_Template $_template, $code) + public function write(\Smarty_Internal_Template $_template, $code) { if (!$_template->source->handler->recompiled) { if ($_template->smarty->ext->_writeFile->writeFile($this->filepath, $code, $_template->smarty) === true) { @@ -218,36 +245,14 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base return true; } - /** - * Load fresh compiled template by including the PHP file - * HHVM requires a work around because of a PHP incompatibility - * - * @param \Smarty_Internal_Template $_smarty_tpl do not change variable name, is used by compiled template - */ - private function loadCompiledTemplate(Smarty_Internal_Template $_smarty_tpl) - { - if (function_exists('opcache_invalidate') - && (!function_exists('ini_get') || strlen(ini_get("opcache.restrict_api")) < 1) - ) { - opcache_invalidate($this->filepath, true); - } elseif (function_exists('apc_compile_file')) { - apc_compile_file($this->filepath); - } - if (defined('HHVM_VERSION')) { - eval("?>" . file_get_contents($this->filepath)); - } else { - include($this->filepath); - } - } - /** * Read compiled content from handler * - * @param Smarty_Internal_Template $_template template object + * @param \Smarty_Internal_Template $_template template object * * @return string content */ - public function read(Smarty_Internal_Template $_template) + public function read(\Smarty_Internal_Template $_template) { if (!$_template->source->handler->recompiled) { return file_get_contents($this->filepath);