From 8e9108544af1da6b162e87c0386af6f407279c18 Mon Sep 17 00:00:00 2001 From: Uwe Tews Date: Thu, 26 Oct 2017 04:36:41 +0200 Subject: [PATCH] - bugfix Smarty version was not filled in header comment of compiled and cached files - optimization replace internal Smarty::$ds property by DIRECTORY_SEPARATOR (reverted from commit 1e787d08f11d0a41028d847428068bf5f8d1c2ac) (reverted from commit 42a292d56aae611a687a2fb5058701d89e13ac1a) --- change_log.txt | 4 + libs/Smarty.class.php | 162 +++++----- .../smarty_internal_compile_include.php | 37 +-- .../smarty_internal_compile_insert.php | 16 +- ..._internal_method_clearcompiledtemplate.php | 31 +- .../smarty_internal_resource_file.php | 18 +- ...smarty_internal_runtime_getincludepath.php | 19 +- .../smarty_internal_runtime_writefile.php | 29 +- libs/sysplugins/smarty_resource.php | 279 +++++++++--------- libs/sysplugins/smarty_template_compiled.php | 62 ++-- 10 files changed, 309 insertions(+), 348 deletions(-) diff --git a/change_log.txt b/change_log.txt index 982085f6..9ccfa305 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,4 +1,8 @@ ===== 3.1.32 - dev === +26.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..4de846a0 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 * @@ -769,27 +763,6 @@ class Smarty extends Smarty_Internal_TemplateBase return $this; } - /** - * Set template directory - * - * @param string|array $template_dir directory(s) of template sources - * @param bool $isConfig true for config_dir - * - * @return \Smarty current Smarty instance for chaining - */ - public function setTemplateDir($template_dir, $isConfig = false) - { - if ($isConfig) { - $this->config_dir = array(); - $this->_processedConfigDir = array(); - } else { - $this->template_dir = array(); - $this->_processedTemplateDir = array(); - } - $this->addTemplateDir($template_dir, null, $isConfig); - return $this; - } - /** * Add template directory(s) * @@ -859,15 +832,24 @@ class Smarty extends Smarty_Internal_TemplateBase } /** - * Set config directory + * Set template directory * - * @param $config_dir + * @param string|array $template_dir directory(s) of template sources + * @param bool $isConfig true for config_dir * - * @return Smarty current Smarty instance for chaining + * @return \Smarty current Smarty instance for chaining */ - public function setConfigDir($config_dir) + public function setTemplateDir($template_dir, $isConfig = false) { - return $this->setTemplateDir($config_dir, true); + if ($isConfig) { + $this->config_dir = array(); + $this->_processedConfigDir = array(); + } else { + $this->template_dir = array(); + $this->_processedTemplateDir = array(); + } + $this->addTemplateDir($template_dir, null, $isConfig); + return $this; } /** @@ -896,17 +878,15 @@ class Smarty extends Smarty_Internal_TemplateBase } /** - * Set plugins directory + * Set config directory * - * @param string|array $plugins_dir directory(s) of plugins + * @param $config_dir * * @return Smarty current Smarty instance for chaining */ - public function setPluginsDir($plugins_dir) + public function setConfigDir($config_dir) { - $this->plugins_dir = (array)$plugins_dir; - $this->_pluginsDirNormalized = false; - return $this; + return $this->setTemplateDir($config_dir, true); } /** @@ -942,7 +922,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; @@ -951,15 +931,16 @@ class Smarty extends Smarty_Internal_TemplateBase } /** + * Set plugins directory * - * @param string $compile_dir directory to store compiled templates in + * @param string|array $plugins_dir directory(s) of plugins * - * @return Smarty current Smarty instance for chaining + * @return Smarty current Smarty instance for chaining */ - public function setCompileDir($compile_dir) + public function setPluginsDir($plugins_dir) { - $this->_normalizeDir('compile_dir', $compile_dir); - $this->_compileDirNormalized = true; + $this->plugins_dir = (array)$plugins_dir; + $this->_pluginsDirNormalized = false; return $this; } @@ -978,16 +959,15 @@ class Smarty extends Smarty_Internal_TemplateBase } /** - * Set cache directory * - * @param string $cache_dir directory to store cached templates in + * @param string $compile_dir directory to store compiled templates in * * @return Smarty current Smarty instance for chaining */ - public function setCacheDir($cache_dir) + public function setCompileDir($compile_dir) { - $this->_normalizeDir('cache_dir', $cache_dir); - $this->_cacheDirNormalized = true; + $this->_normalizeDir('compile_dir', $compile_dir); + $this->_compileDirNormalized = true; return $this; } @@ -1005,6 +985,20 @@ class Smarty extends Smarty_Internal_TemplateBase return $this->cache_dir; } + /** + * Set cache directory + * + * @param string $cache_dir directory to store cached templates in + * + * @return Smarty current Smarty instance for chaining + */ + public function setCacheDir($cache_dir) + { + $this->_normalizeDir('cache_dir', $cache_dir); + $this->_cacheDirNormalized = true; + return $this; + } + /** * creates a template object * @@ -1133,24 +1127,24 @@ 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); $path = $parts[ 'path' ]; - if ($parts[ 'root' ] == '\\') { + if ($parts[ 'root' ] === '\\') { $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); } } @@ -1209,16 +1203,6 @@ class Smarty extends Smarty_Internal_TemplateBase $this->escape_html = $escape_html; } - /** - * Set auto_literal flag - * - * @param boolean $auto_literal - */ - public function setAutoLiteral($auto_literal = true) - { - $this->auto_literal = $auto_literal; - } - /** * Return auto_literal flag * @@ -1229,6 +1213,16 @@ class Smarty extends Smarty_Internal_TemplateBase return $this->auto_literal; } + /** + * Set auto_literal flag + * + * @param boolean $auto_literal + */ + public function setAutoLiteral($auto_literal = true) + { + $this->auto_literal = $auto_literal; + } + /** * @param boolean $force_compile */ @@ -1245,16 +1239,6 @@ class Smarty extends Smarty_Internal_TemplateBase $this->merge_compiled_includes = $merge_compiled_includes; } - /** - * Set left delimiter - * - * @param string $left_delimiter - */ - public function setLeftDelimiter($left_delimiter) - { - $this->left_delimiter = $left_delimiter; - } - /** * Get left delimiter * @@ -1266,13 +1250,13 @@ class Smarty extends Smarty_Internal_TemplateBase } /** - * Set right delimiter + * Set left delimiter * - * @param string + * @param string $left_delimiter */ - public function setRightDelimiter($right_delimiter) + public function setLeftDelimiter($left_delimiter) { - $this->right_delimiter = $right_delimiter; + $this->left_delimiter = $left_delimiter; } /** @@ -1285,6 +1269,16 @@ class Smarty extends Smarty_Internal_TemplateBase return $this->right_delimiter; } + /** + * Set right delimiter + * + * @param string + */ + public function setRightDelimiter($right_delimiter) + { + $this->right_delimiter = $right_delimiter; + } + /** * @param boolean $debugging */ @@ -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_compile_include.php b/libs/sysplugins/smarty_internal_compile_include.php index a81b0c74..6fdbe258 100644 --- a/libs/sysplugins/smarty_internal_compile_include.php +++ b/libs/sysplugins/smarty_internal_compile_include.php @@ -20,7 +20,6 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase * caching mode to create nocache code but no cache file */ const CACHING_NOCACHE_CODE = 9999; - /** * Attribute definition: Overwrites base class. * @@ -28,7 +27,6 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase * @see Smarty_Internal_CompileBase */ public $required_attributes = array('file'); - /** * Attribute definition: Overwrites base class. * @@ -36,7 +34,6 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase * @see Smarty_Internal_CompileBase */ public $shorttag_order = array('file'); - /** * Attribute definition: Overwrites base class. * @@ -44,7 +41,6 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase * @see Smarty_Internal_CompileBase */ public $option_flags = array('nocache', 'inline', 'caching'); - /** * Attribute definition: Overwrites base class. * @@ -52,7 +48,6 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase * @see Smarty_Internal_CompileBase */ public $optional_attributes = array('_any'); - /** * Valid scope names * @@ -77,7 +72,6 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase $uid = $t_hash = null; // check and get attributes $_attr = $this->getAttributes($compiler, $args); - $fullResourceName = $source_resource = $_attr[ 'file' ]; $variable_template = false; $cache_tpl = false; @@ -90,11 +84,11 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase $variable_template = true; } if (!$variable_template) { - if ($type != 'string') { + if ($type !== 'string') { $fullResourceName = "{$type}:{$name}"; $compiled = $compiler->parent_compiler->template->compiled; if (isset($compiled->includes[ $fullResourceName ])) { - $compiled->includes[ $fullResourceName ] ++; + $compiled->includes[ $fullResourceName ]++; $cache_tpl = true; } else { if ("{$compiler->template->source->type}:{$compiler->template->source->name}" == @@ -116,10 +110,8 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase } else { $variable_template = true; } - // scope setup $_scope = $compiler->convertScope($_attr, $this->valid_scopes); - // set flag to cache subtemplate object when called within loop or template name is variable. if ($cache_tpl || $variable_template || $compiler->loopNesting > 0) { $_cache_tpl = 'true'; @@ -128,18 +120,14 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase } // assume caching is off $_caching = Smarty::CACHING_OFF; - $call_nocache = $compiler->tag_nocache || $compiler->nocache; - // caching was on and {include} is not in nocache mode if ($compiler->template->caching && !$compiler->nocache && !$compiler->tag_nocache) { $_caching = self::CACHING_NOCACHE_CODE; } - // flag if included template code should be merged into caller $merge_compiled_includes = ($compiler->smarty->merge_compiled_includes || $_attr[ 'inline' ] === true) && !$compiler->template->source->handler->recompiled; - if ($merge_compiled_includes) { // variable template name ? if ($variable_template) { @@ -150,7 +138,6 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase $merge_compiled_includes = false; } } - /* * if the {include} tag provides individual parameter for caching or compile_id * the subtemplate must not be included into the common cache file and is treated like @@ -158,7 +145,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase * */ if ($_attr[ 'nocache' ] !== true && $_attr[ 'caching' ]) { - $_caching = $_new_caching = (int) $_attr[ 'caching' ]; + $_caching = $_new_caching = (int)$_attr[ 'caching' ]; $call_nocache = true; } else { $_new_caching = Smarty::CACHING_LIFETIME_CURRENT; @@ -182,7 +169,6 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase } else { $_compile_id = '$_smarty_tpl->compile_id'; } - // if subtemplate will be called in nocache mode do not merge if ($compiler->template->caching && $call_nocache) { $merge_compiled_includes = false; @@ -200,7 +186,6 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase $_assign = $_attr[ 'assign' ]; } } - $has_compiled_template = false; if ($merge_compiled_includes) { $c_id = isset($_attr[ 'compile_id' ]) ? $_attr[ 'compile_id' ] : $compiler->template->compile_id; @@ -232,17 +217,17 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase $_vars = 'array(' . join(',', $_pairs) . ')'; } $update_compile_id = $compiler->template->caching && !$compiler->tag_nocache && !$compiler->nocache && - $_compile_id != '$_smarty_tpl->compile_id'; + $_compile_id !== '$_smarty_tpl->compile_id'; if ($has_compiled_template && !$call_nocache) { $_output = "makeNocacheCode("\$_compile_id_save[] = \$_smarty_tpl->compile_id;\n\$_smarty_tpl->compile_id = {$_compile_id};\n"); } - if (!empty($_attr) && $_caching == 9999 && $compiler->template->caching) { + if (!empty($_attr) && $_caching === 9999 && $compiler->template->caching) { $_vars_nc = "foreach ($_vars as \$ik => \$iv) {\n"; $_vars_nc .= "\$_smarty_tpl->tpl_vars[\$ik] = new Smarty_Variable(\$iv);\n"; $_vars_nc .= "}\n"; - $_output .= substr($compiler->processNocacheCode('\n", true), 6, - 3); + $_output .= substr($compiler->processNocacheCode('\n", true), 6, -3); } if (isset($_assign)) { $_output .= "ob_start();\n"; @@ -255,10 +240,8 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase $_output .= $compiler->makeNocacheCode("\$_smarty_tpl->compile_id = array_pop(\$_compile_id_save);\n"); } $_output .= "?>\n"; - return $_output; } - if ($call_nocache) { $compiler->tag_nocache = true; } @@ -291,7 +274,8 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase * @return bool */ public function compileInlineTemplate(Smarty_Internal_SmartyTemplateCompiler $compiler, - Smarty_Internal_Template $tpl, $t_hash) + Smarty_Internal_Template $tpl, + $t_hash) { $uid = $tpl->source->type . $tpl->source->uid; if (!($tpl->source->handler->uncompiled) && $tpl->source->exists) { @@ -309,7 +293,7 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase $tpl->mustCompile = true; $compiler->parent_compiler->mergedSubTemplatesData[ $uid ][ $t_hash ][ 'nocache_hash' ] = $tpl->compiled->nocache_hash; - if ($compiler->template->source->type == 'file') { + if ($compiler->template->source->type === 'file') { $sourceInfo = $compiler->template->source->filepath; } else { $basename = $compiler->template->source->handler->getBasename($compiler->template->source); @@ -331,7 +315,8 @@ class Smarty_Internal_Compile_Include extends Smarty_Internal_CompileBase if ($tpl->compiled->has_nocache_code) { // replace nocache_hash $compiled_code = - str_replace("{$tpl->compiled->nocache_hash}", $compiler->template->compiled->nocache_hash, + str_replace("{$tpl->compiled->nocache_hash}", + $compiler->template->compiled->nocache_hash, $compiled_code); $compiler->template->compiled->has_nocache_code = true; } diff --git a/libs/sysplugins/smarty_internal_compile_insert.php b/libs/sysplugins/smarty_internal_compile_insert.php index 02ef67c3..117ec4ef 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 +62,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 +108,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 +118,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 +146,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_clearcompiledtemplate.php b/libs/sysplugins/smarty_internal_method_clearcompiledtemplate.php index 0ed9f95b..1d448e5f 100644 --- a/libs/sysplugins/smarty_internal_method_clearcompiledtemplate.php +++ b/libs/sysplugins/smarty_internal_method_clearcompiledtemplate.php @@ -35,13 +35,12 @@ class Smarty_Internal_Method_ClearCompiledTemplate { // clear template objects cache $smarty->_clearTemplateCache(); - $_compile_dir = $smarty->getCompileDir(); - if ($_compile_dir == '/') { //We should never want to delete this! + if ($_compile_dir === '/') { //We should never want to delete this! return 0; } $_compile_id = isset($compile_id) ? preg_replace('![^\w]+!', '_', $compile_id) : null; - $_dir_sep = $smarty->use_sub_dirs ? $smarty->ds : '^'; + $_dir_sep = $smarty->use_sub_dirs ? DIRECTORY_SEPARATOR : '^'; if (isset($resource_name)) { $_save_stat = $smarty->caching; $smarty->caching = false; @@ -49,7 +48,7 @@ class Smarty_Internal_Method_ClearCompiledTemplate $tpl = $smarty->createTemplate($resource_name); $smarty->caching = $_save_stat; if (!$tpl->source->handler->uncompiled && !$tpl->source->handler->recompiled && $tpl->source->exists) { - $_resource_part_1 = basename(str_replace('^', $smarty->ds, $tpl->compiled->filepath)); + $_resource_part_1 = basename(str_replace('^', DIRECTORY_SEPARATOR, $tpl->compiled->filepath)); $_resource_part_1_length = strlen($_resource_part_1); } else { return 0; @@ -75,10 +74,10 @@ class Smarty_Internal_Method_ClearCompiledTemplate } $_compile = new RecursiveIteratorIterator($_compileDirs, RecursiveIteratorIterator::CHILD_FIRST); foreach ($_compile as $_file) { - if (substr(basename($_file->getPathname()), 0, 1) == '.') { + if (substr(basename($_file->getPathname()), 0, 1) === '.') { continue; } - $_filepath = (string) $_file; + $_filepath = (string)$_file; if ($_file->isDir()) { if (!$_compile->isDot()) { // delete folder if empty @@ -86,19 +85,22 @@ class Smarty_Internal_Method_ClearCompiledTemplate } } else { // delete only php files - if (substr($_filepath, - 4) !== '.php') { + if (substr($_filepath, -4) !== '.php') { continue; } $unlink = false; if ((!isset($_compile_id) || (isset($_filepath[ $_compile_id_part_length ]) && $a = !strncmp($_filepath, $_compile_id_part, $_compile_id_part_length))) && (!isset($resource_name) || (isset($_filepath[ $_resource_part_1_length ]) && - substr_compare($_filepath, $_resource_part_1, - - $_resource_part_1_length, $_resource_part_1_length) == + substr_compare($_filepath, + $_resource_part_1, + -$_resource_part_1_length, + $_resource_part_1_length) === 0) || (isset($_filepath[ $_resource_part_2_length ]) && - substr_compare($_filepath, $_resource_part_2, - - $_resource_part_2_length, - $_resource_part_2_length) == 0)) + substr_compare($_filepath, + $_resource_part_2, + -$_resource_part_2_length, + $_resource_part_2_length) === 0)) ) { if (isset($exp_time)) { if (is_file($_filepath) && time() - @filemtime($_filepath) >= $exp_time) { @@ -108,14 +110,13 @@ class Smarty_Internal_Method_ClearCompiledTemplate $unlink = true; } } - if ($unlink && is_file($_filepath) && @unlink($_filepath)) { - $_count ++; + $_count++; if (function_exists('opcache_invalidate') && (!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_resource_file.php b/libs/sysplugins/smarty_internal_resource_file.php index a58771a1..f8b361a9 100644 --- a/libs/sysplugins/smarty_internal_resource_file.php +++ b/libs/sysplugins/smarty_internal_resource_file.php @@ -30,32 +30,32 @@ class Smarty_Internal_Resource_File extends Smarty_Resource { $file = $source->name; // absolute file ? - if ($file[ 0 ] == '/' || $file[ 1 ] == ':') { + if ($file[ 0 ] === '/' || $file[ 1 ] === ':') { $file = $source->smarty->_realpath($file, true); return is_file($file) ? $file : false; } // go relative to a given template? - if ($file[ 0 ] == '.' && $_template && $_template->_isSubTpl() && + if ($file[ 0 ] === '.' && $_template && $_template->_isSubTpl() && preg_match('#^[.]{1,2}[\\\/]#', $file) ) { - if ($_template->parent->source->type != 'file' && $_template->parent->source->type != 'extends' && + if ($_template->parent->source->type !== 'file' && $_template->parent->source->type !== 'extends' && !isset($_template->parent->_cache[ 'allow_relative_path' ]) ) { 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)) { + if ($file[ 0 ] === '[' && preg_match('#^\[([^\]]+)\](.+)$#', $file, $fileMatch)) { $file = $fileMatch[ 2 ]; $_indices = explode(',', $fileMatch[ 1 ]); $_index_dirs = array(); @@ -90,7 +90,7 @@ class Smarty_Internal_Resource_File extends Smarty_Resource 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)) { diff --git a/libs/sysplugins/smarty_internal_runtime_getincludepath.php b/libs/sysplugins/smarty_internal_runtime_getincludepath.php index e12b0c57..00dbf7b5 100644 --- a/libs/sysplugins/smarty_internal_runtime_getincludepath.php +++ b/libs/sysplugins/smarty_internal_runtime_getincludepath.php @@ -21,49 +21,42 @@ class Smarty_Internal_Runtime_GetIncludePath * @var string */ public $_include_path = ''; - /** * include path directory cache * * @var array */ public $_include_dirs = array(); - /** * include path directory cache * * @var array */ public $_user_dirs = array(); - /** * stream cache * * @var string[] */ public $isFile = array(); - /** * stream cache * * @var string[] */ public $isPath = array(); - /** * stream cache * * @var int[] */ public $number = array(); - /** * status cache * * @var bool */ public $_has_stream_include = null; - /** * Number for array index * @@ -81,13 +74,13 @@ class Smarty_Internal_Runtime_GetIncludePath public function isNewIncludePath(Smarty $smarty) { $_i_path = get_include_path(); - if ($this->_include_path != $_i_path) { + if ($this->_include_path !== $_i_path) { $this->_include_dirs = array(); $this->_include_path = $_i_path; - $_dirs = (array) explode(PATH_SEPARATOR, $_i_path); + $_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; @@ -128,7 +121,7 @@ class Smarty_Internal_Runtime_GetIncludePath } // try PHP include_path foreach ($dirs as $dir) { - $dir_n = isset($this->number[ $dir ]) ? $this->number[ $dir ] : $this->number[ $dir ] = $this->counter ++; + $dir_n = isset($this->number[ $dir ]) ? $this->number[ $dir ] : $this->number[ $dir ] = $this->counter++; if (isset($this->isFile[ $dir_n ][ $file ])) { if ($this->isFile[ $dir_n ][ $file ]) { return $this->isFile[ $dir_n ][ $file ]; @@ -143,9 +136,9 @@ class Smarty_Internal_Runtime_GetIncludePath $dir = $this->_user_dirs[ $dir_n ]; } } else { - if ($dir[ 0 ] == '/' || $dir[ 1 ] == ':') { + if ($dir[ 0 ] === '/' || $dir[ 1 ] === ':') { $dir = str_ireplace(getcwd(), '.', $dir); - if ($dir[ 0 ] == '/' || $dir[ 1 ] == ':') { + if ($dir[ 0 ] === '/' || $dir[ 1 ] === ':') { $this->_user_dirs[ $dir_n ] = false; continue; } 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..4aaafa4d 100644 --- a/libs/sysplugins/smarty_resource.php +++ b/libs/sysplugins/smarty_resource.php @@ -20,32 +20,29 @@ */ 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 * * @var boolean */ public $uncompiled = false; - /** * Source must be recompiled on every occasion * * @var boolean */ 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 +50,124 @@ abstract class Smarty_Resource */ public $hasCompiledHandler = false; + /** + * 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) . DIRECTORY_SEPARATOR . $name); + } + return $resource->buildUniqueResourceName($smarty, $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 + */ + 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 * @@ -105,6 +220,13 @@ abstract class Smarty_Resource } } + /* + * 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 + */ + /** * Determine basename for compiled filename * @@ -117,138 +239,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..b45cd8b1 100644 --- a/libs/sysplugins/smarty_template_compiled.php +++ b/libs/sysplugins/smarty_template_compiled.php @@ -11,7 +11,6 @@ */ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base { - /** * nocache hash * @@ -49,21 +48,22 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base $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 : '^'); } // 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 .= $source->uid[ 0 ] . $source->uid[ 1 ] . DIRECTORY_SEPARATOR . $source->uid[ 2 ] . + $source->uid[ 3 ] . DIRECTORY_SEPARATOR . $source->uid[ 4 ] . $source->uid[ 5 ] . + DIRECTORY_SEPARATOR; } $this->filepath .= $source->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); @@ -134,7 +134,7 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base $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()) ) { @@ -218,28 +218,6 @@ 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 * @@ -254,4 +232,26 @@ class Smarty_Template_Compiled extends Smarty_Template_Resource_Base } return isset($this->content) ? $this->content : false; } + + /** + * 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); + } + } }