- optimization of directory handling / build realpath

This commit is contained in:
Uwe Tews
2015-06-21 13:11:52 +02:00
parent 31d94d05d3
commit c09b05cbe3
3 changed files with 131 additions and 80 deletions

View File

@@ -1,6 +1,7 @@
 ===== 3.1.28-dev===== (xx.xx.2015)  ===== 3.1.28-dev===== (xx.xx.2015)
21.06.2015 21.06.2015
- optimization of template/config file normalization - optimization of template/config file normalization
- optimization of directory handling / build realpath
19.06.2015 19.06.2015
- improvement allow closures as callback at $smarty->registerFilter() https://github.com/smarty-php/smarty/issues/59 - improvement allow closures as callback at $smarty->registerFilter() https://github.com/smarty-php/smarty/issues/59

View File

@@ -111,7 +111,7 @@ class Smarty extends Smarty_Internal_TemplateBase
/** /**
* smarty version * smarty version
*/ */
const SMARTY_VERSION = '3.1.28-dev/2'; const SMARTY_VERSION = '3.1.28-dev/3';
/** /**
* define variable scopes * define variable scopes
@@ -134,7 +134,7 @@ class Smarty extends Smarty_Internal_TemplateBase
const CACHING_LIFETIME_SAVED = 2; const CACHING_LIFETIME_SAVED = 2;
/** /**
* define constant for clearing cache files be saved expiration datees * define constant for clearing cache files be saved expiration dates
*/ */
const CLEAR_EXPIRED = - 1; const CLEAR_EXPIRED = - 1;
@@ -199,14 +199,14 @@ class Smarty extends Smarty_Internal_TemplateBase
public static $global_tpl_vars = array(); public static $global_tpl_vars = array();
/** /**
* error handler returned by set_error_hanlder() in Smarty::muteExpectedErrors() * error handler returned by set_error_handler() in Smarty::muteExpectedErrors()
*/ */
public static $_previous_error_handler = null; public static $_previous_error_handler = null;
/** /**
* contains directories outside of SMARTY_DIR that are to be muted by muteExpectedErrors() * contains directories outside of SMARTY_DIR that are to be muted by muteExpectedErrors()
*/ */
public static $_muted_directories = array('./templates_c/' => null, './cache/' => null); public static $_muted_directories = array();
/** /**
* Flag denoting if Multibyte String functions are available * Flag denoting if Multibyte String functions are available
@@ -271,14 +271,14 @@ class Smarty extends Smarty_Internal_TemplateBase
* *
* @var string * @var string
*/ */
public $joined_template_dir = './templates/'; public $joined_template_dir = '';
/** /**
* joined config directory string used in cache keys * joined config directory string used in cache keys
* *
* @var string * @var string
*/ */
public $joined_config_dir = './configs/'; public $joined_config_dir = '';
/** /**
* default template handler * default template handler
@@ -524,7 +524,7 @@ class Smarty extends Smarty_Internal_TemplateBase
public $compile_locking = true; public $compile_locking = true;
/** /**
* Controls whether cache resources should emply locking mechanism * Controls whether cache resources should use locking mechanism
* *
* @var boolean * @var boolean
*/ */
@@ -744,6 +744,13 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
public $_is_file_cache = array(); public $_is_file_cache = array();
/**
* Cache of internal flags
*
* @var array
*/
public $_flags = array();
/**#@-*/ /**#@-*/
/** /**
@@ -755,26 +762,7 @@ class Smarty extends Smarty_Internal_TemplateBase
mb_internal_encoding(Smarty::$_CHARSET); mb_internal_encoding(Smarty::$_CHARSET);
} }
$this->start_time = microtime(true); $this->start_time = microtime(true);
// check default dirs for overloading
if ($this->template_dir[0] !== './templates/' || isset($this->template_dir[1])) {
$this->setTemplateDir($this->template_dir);
}
if ($this->config_dir[0] !== './configs/' || isset($this->config_dir[1])) {
$this->setConfigDir($this->config_dir);
}
if ($this->compile_dir !== './templates_c/') {
unset(self::$_muted_directories['./templates_c/']);
$this->setCompileDir($this->compile_dir);
}
if ($this->cache_dir !== './cache/') {
unset(self::$_muted_directories['./cache/']);
$this->setCacheDir($this->cache_dir);
}
if (isset($this->plugins_dir)) {
$this->setPluginsDir($this->plugins_dir);
} else {
$this->setPluginsDir(SMARTY_PLUGINS_DIR);
}
if (isset($_SERVER['SCRIPT_NAME'])) { if (isset($_SERVER['SCRIPT_NAME'])) {
Smarty::$global_tpl_vars['SCRIPT_NAME'] = new Smarty_Variable($_SERVER['SCRIPT_NAME']); Smarty::$global_tpl_vars['SCRIPT_NAME'] = new Smarty_Variable($_SERVER['SCRIPT_NAME']);
} }
@@ -962,16 +950,17 @@ class Smarty extends Smarty_Internal_TemplateBase
* Set template directory * Set template directory
* *
* @param string|array $template_dir directory(s) of template sources * @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 setTemplateDir($template_dir) public function setTemplateDir($template_dir, $isConfig = false)
{ {
$this->template_dir = array(); $type = $isConfig ? 'config_dir' : 'template_dir';
foreach ((array) $template_dir as $k => $v) { $joined = 'joined_' . $type;
$this->template_dir[$k] = rtrim($v, '/\\') . DS; $this->{$type} = (array) $template_dir;
} $this->{$joined} = join(' # ', $this->{$type});
$this->joined_template_dir = join(' # ', $this->template_dir); $this->_flags[$type] = false;
return $this; return $this;
} }
@@ -980,14 +969,21 @@ class Smarty extends Smarty_Internal_TemplateBase
* *
* @param string|array $template_dir directory(s) of template sources * @param string|array $template_dir directory(s) of template sources
* @param string $key of the array element to assign the template dir to * @param string $key of the array element to assign the template dir to
* @param bool $isConfig true for config_dir
* *
* @return Smarty current Smarty instance for chaining * @return Smarty current Smarty instance for chaining
* @throws SmartyException when the given template directory is not valid
*/ */
public function addTemplateDir($template_dir, $key = null) public function addTemplateDir($template_dir, $key = null, $isConfig = false)
{ {
$this->_addDir('template_dir', $template_dir, $key); $type = $isConfig ? 'config_dir' : 'template_dir';
$this->joined_template_dir = join(' # ', $this->template_dir); $joined = 'joined_' . $type;
if (!isset($this->_flags[$type])) {
$this->{$type} = (array) $this->{$type};
$this->{$joined} = join(' # ', $this->{$type});
$this->_flags[$type] = false;
}
$this->{$joined} .= ' # ' . join(' # ', (array) $template_dir);
$this->_addDir($type, $template_dir, $key);
return $this; return $this;
} }
@@ -995,15 +991,29 @@ class Smarty extends Smarty_Internal_TemplateBase
* Get template directories * Get template directories
* *
* @param mixed $index index of directory to get, null to get all * @param mixed $index index of directory to get, null to get all
* @param bool $isConfig true for config_dir
* *
* @return array|string list of template directories, or directory of $index * @return array list of template directories, or directory of $index
*/ */
public function getTemplateDir($index = null) public function getTemplateDir($index = null, $isConfig = false)
{ {
if ($index !== null) { $type = $isConfig ? 'config_dir' : 'template_dir';
return isset($this->template_dir[$index]) ? $this->template_dir[$index] : null; if (!isset($this->_flags[$type])) {
$joined = 'joined_' . $type;
$this->{$type} = (array) $this->{$type};
$this->{$joined} = join(' # ', $this->{$type});
$this->_flags[$type] = false;
} }
return (array) $this->template_dir; if ($this->_flags[$type] == false) {
foreach ($this->{$type} as $k => $v) {
$this->{$type}[$k] = $this->_realpath($v . DS);
}
$this->_flags[$type] = true;
}
if ($index !== null) {
return isset($this->{$type}[$index]) ? $this->{$type}[$index] : null;
}
return $this->{$type};
} }
/** /**
@@ -1015,12 +1025,7 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
public function setConfigDir($config_dir) public function setConfigDir($config_dir)
{ {
$this->config_dir = array(); return $this->setTemplateDir($config_dir, true);
foreach ((array) $config_dir as $k => $v) {
$this->config_dir[$k] = rtrim($v, '/\\') . DS;
}
$this->joined_config_dir = join(' # ', $this->config_dir);
return $this;
} }
/** /**
@@ -1033,9 +1038,7 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
public function addConfigDir($config_dir, $key = null) public function addConfigDir($config_dir, $key = null)
{ {
$this->_addDir('config_dir', $config_dir, $key); return $this->addTemplateDir($config_dir, $key, true);
$this->joined_config_dir = join(' # ', $this->config_dir);
return $this;
} }
/** /**
@@ -1043,14 +1046,11 @@ class Smarty extends Smarty_Internal_TemplateBase
* *
* @param mixed $index index of directory to get, null to get all * @param mixed $index index of directory to get, null to get all
* *
* @return array|string configuration directory * @return array configuration directory
*/ */
public function getConfigDir($index = null) public function getConfigDir($index = null)
{ {
if ($index !== null) { return $this->getTemplateDir($index, true);
return isset($this->config_dir[$index]) ? $this->config_dir[$index] : null;
}
return (array) $this->config_dir;
} }
/** /**
@@ -1062,8 +1062,10 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
public function setPluginsDir($plugins_dir) public function setPluginsDir($plugins_dir)
{ {
$this->plugins_dir = array(); $this->plugins_dir = (array) $plugins_dir;
$this->addPluginsDir($plugins_dir); if (isset($this->_flags['plugins_dir'])) {
unset($this->_flags['plugins_dir']);
}
return $this; return $this;
} }
@@ -1076,13 +1078,13 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
public function addPluginsDir($plugins_dir) public function addPluginsDir($plugins_dir)
{ {
// make sure we're dealing with an array if (!isset($this->plugins_dir)) {
$this->plugins_dir = (array) $this->plugins_dir; $this->plugins_dir = array(SMARTY_PLUGINS_DIR);
foreach ((array) $plugins_dir as $v) { }
$this->plugins_dir[] = rtrim($v, '/\\') . DS; $this->plugins_dir = array_merge((array) $this->plugins_dir, (array) $plugins_dir);
if (isset($this->_flags['plugins_dir'])) {
unset($this->_flags['plugins_dir']);
} }
$this->plugins_dir = array_unique($this->plugins_dir);
$this->_is_file_cache = array();
return $this; return $this;
} }
@@ -1093,7 +1095,21 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
public function getPluginsDir() public function getPluginsDir()
{ {
return (array) $this->plugins_dir; if (!isset($this->_flags['plugins_dir'])) {
if (!isset($this->plugins_dir)) {
$this->plugins_dir = array(SMARTY_PLUGINS_DIR);
} else {
$plugins_dir = (array) $this->plugins_dir;
$this->plugins_dir = array();
foreach ($plugins_dir as $v) {
$this->plugins_dir[] = $this->_realpath($v . DS);
}
$this->plugins_dir = array_unique($this->plugins_dir);
}
$this->_is_file_cache = array();
$this->_flags['plugins_dir'] = true;
}
return $this->plugins_dir;
} }
/** /**
@@ -1105,11 +1121,11 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
public function setCompileDir($compile_dir) public function setCompileDir($compile_dir)
{ {
$this->compile_dir = rtrim($compile_dir, '/\\') . DS; $this->compile_dir = $this->_realpath($compile_dir . DS);
if (!isset(Smarty::$_muted_directories[$this->compile_dir])) { if (!isset(Smarty::$_muted_directories[$this->compile_dir])) {
Smarty::$_muted_directories[$this->compile_dir] = null; Smarty::$_muted_directories[$this->compile_dir] = null;
} }
$this->_flags['compile_dir'] = true;
return $this; return $this;
} }
@@ -1120,6 +1136,13 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
public function getCompileDir() public function getCompileDir()
{ {
if (!isset($this->_flags['compile_dir'])) {
$this->compile_dir = $this->_realpath($this->compile_dir . DS);
if (!isset(Smarty::$_muted_directories[$this->compile_dir])) {
Smarty::$_muted_directories[$this->compile_dir] = null;
}
$this->_flags['compile_dir'] = true;
}
return $this->compile_dir; return $this->compile_dir;
} }
@@ -1132,10 +1155,11 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
public function setCacheDir($cache_dir) public function setCacheDir($cache_dir)
{ {
$this->cache_dir = rtrim($cache_dir, '/\\') . DS; $this->cache_dir = $this->_realpath($cache_dir . DS);
if (!isset(Smarty::$_muted_directories[$this->cache_dir])) { if (!isset(Smarty::$_muted_directories[$this->cache_dir])) {
Smarty::$_muted_directories[$this->cache_dir] = null; Smarty::$_muted_directories[$this->cache_dir] = null;
} }
$this->_flags['cache_dir'] = true;
return $this; return $this;
} }
@@ -1146,6 +1170,13 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
public function getCacheDir() public function getCacheDir()
{ {
if (!isset($this->_flags['cache_dir'])) {
$this->cache_dir = $this->_realpath($this->cache_dir . DS);
if (!isset(Smarty::$_muted_directories[$this->cache_dir])) {
Smarty::$_muted_directories[$this->cache_dir] = null;
}
$this->_flags['cache_dir'] = true;
}
return $this->cache_dir; return $this->cache_dir;
} }
@@ -1158,26 +1189,26 @@ class Smarty extends Smarty_Internal_TemplateBase
*/ */
private function _addDir($dirName, $dir, $key = null) private function _addDir($dirName, $dir, $key = null)
{ {
// make sure we're dealing with an array $rp = $this->_flags[$dirName];
$this->$dirName = (array) $this->$dirName;
if (is_array($dir)) { if (is_array($dir)) {
foreach ($dir as $k => $v) { foreach ($dir as $k => $v) {
$path = $rp ? $this->_realpath($v . DS) : $v;
if (is_int($k)) { if (is_int($k)) {
// indexes are not merged but appended // indexes are not merged but appended
$this->{$dirName}[] = rtrim($v, '/\\') . DS; $this->{$dirName}[] = $path;
} else { } else {
// string indexes are overridden // string indexes are overridden
$this->{$dirName}[$k] = rtrim($v, '/\\') . DS; $this->{$dirName}[$k] = $path;
} }
} }
} else { } else {
$path = $rp ? $this->_realpath($dir . DS) : $dir;
if ($key !== null) { if ($key !== null) {
// override directory at specified index // override directory at specified index
$this->{$dirName}[$key] = rtrim($dir, '/\\') . DS; $this->{$dirName}[$key] = $path;
} else { } else {
// append new directory // append new directory
$this->{$dirName}[] = rtrim($dir, '/\\') . DS; $this->{$dirName}[] = $path;
} }
} }
} }
@@ -1287,7 +1318,6 @@ class Smarty extends Smarty_Internal_TemplateBase
if ($type !== null) { if ($type !== null) {
return isset($this->autoload_filters[$type]) ? $this->autoload_filters[$type] : array(); return isset($this->autoload_filters[$type]) ? $this->autoload_filters[$type] : array();
} }
return $this->autoload_filters; return $this->autoload_filters;
} }
@@ -1440,6 +1470,29 @@ class Smarty extends Smarty_Internal_TemplateBase
return false; return false;
} }
/**
* Normalize path
* - remove /./ and /../
* - make it absolute
*
* @param string $path file path
*
* @return string
*/
public function _realpath($path)
{
if ($path[0] == '.') {
$path = getcwd() . DS . $path;
}
//return realpath($path) . DS;
$first = true;
while ($first || strrpos($path, '.' . DS) !== false) {
$path = preg_replace('#([\\\/]([^\\\/]+[\\\/]){2}([.][.][\\\/]){2})|([\\\/][^\\\/]+[\\\/][.][.][\\\/])|([\\\/]+([.][\\\/]+)*)#', DS, $path);
$first = false;
}
return $path;
}
/** /**
* Compile all template files * Compile all template files
* *

View File

@@ -130,9 +130,6 @@ class Smarty_Internal_Resource_File extends Smarty_Resource
*/ */
public function normalizePath($path) public function normalizePath($path)
{ {
if ($path[0] == '.') {
$path = getcwd() . DS . $path;
}
$first = true; $first = true;
while (strrpos($path, '.' . DS) !== false || ($first && strrpos($path, $this->invDS) !== false)) { while (strrpos($path, '.' . DS) !== false || ($first && strrpos($path, $this->invDS) !== false)) {
$path = preg_replace('#([\\\/]+([.][\\\/]+)+)|([\\\/]+([^\\\/]+[\\\/]+){2}([.][.][\\\/]+){2})|([\\\/]+[^\\\/]+[\\\/]+[.][.][\\\/]+)|[' . $this->invDS . ']+#', DS, $path); $path = preg_replace('#([\\\/]+([.][\\\/]+)+)|([\\\/]+([^\\\/]+[\\\/]+){2}([.][.][\\\/]+){2})|([\\\/]+[^\\\/]+[\\\/]+[.][.][\\\/]+)|[' . $this->invDS . ']+#', DS, $path);