diff --git a/change_log.txt b/change_log.txt index 9d8bab62..dac8484d 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,7 +1,7 @@ ===== Smarty 3.1 trunk ===== 21.09.2011 - bugfix look for mixed case plugin file names as in 3.0 if not found try all lowercase -- bugfix use 3.0 version of smarty_internal_write_file.php because of problems with custom error handlers +- added $error_muting to suppress error messages even for badly implemented error_handlers 20.09.2011 - bugfix removed debug echo output while compiling template inheritance diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index 9ea46041..5ad5f746 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -157,6 +157,11 @@ class Smarty extends Smarty_Internal_TemplateBase { * assigned global tpl vars */ public static $global_tpl_vars = array(); + /** + * Enable error_handler suppression to outsmart badly implemented external error_handlers + * @var boolean + */ + public static $error_muting = true; /**#@+ * variables @@ -684,10 +689,13 @@ class Smarty extends Smarty_Internal_TemplateBase { */ function clearAllCache($exp_time = null, $type = null) { + Smarty::muteExpectedErrors(); // load cache resource and call clearAll $_cache_resource = Smarty_CacheResource::load($this, $type); Smarty_CacheResource::invalidLoadedCache($this); - return $_cache_resource->clearAll($this, $exp_time); + $t = $_cache_resource->clearAll($this, $exp_time); + Smarty::unmuteExpectedErrors(); + return $t; } /** @@ -702,10 +710,13 @@ class Smarty extends Smarty_Internal_TemplateBase { */ public function clearCache($template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null) { + Smarty::muteExpectedErrors(); // load cache resource and call clear $_cache_resource = Smarty_CacheResource::load($this, $type); Smarty_CacheResource::invalidLoadedCache($this); - return $_cache_resource->clear($this, $template_name, $cache_id, $compile_id, $exp_time); + $t = $_cache_resource->clear($this, $template_name, $cache_id, $compile_id, $exp_time); + Smarty::unmuteExpectedErrors(); + return $t; } /** @@ -1178,7 +1189,8 @@ class Smarty extends Smarty_Internal_TemplateBase { // Plugin name is expected to be: Smarty_[Type]_[Name] $_name_parts = explode('_', $plugin_name, 3); // class name must have three parts to be valid plugin - if (count($_name_parts) < 3 || strtolower($_name_parts[0]) !== 'smarty') { + // count($_name_parts) < 3 === !isset($_name_parts[2]) + if (!isset($_name_parts[2]) || strtolower($_name_parts[0]) !== 'smarty') { throw new SmartyException("plugin {$plugin_name} is not a valid name format"); return false; } @@ -1196,9 +1208,10 @@ class Smarty extends Smarty_Internal_TemplateBase { $_plugin_filename = "{$_name_parts[1]}.{$_name_parts[2]}.php"; // loop through plugin dirs and find the plugin foreach($this->getPluginsDir() as $_plugin_dir) { - $names = array(); - $names[] = $_plugin_dir . $_plugin_filename; - $names[] = $_plugin_dir . strtolower($_plugin_filename); + $names = array( + // $_plugin_dir . $_plugin_filename, + $_plugin_dir . strtolower($_plugin_filename), + ); foreach ($names as $file) { if (file_exists($file)) { require_once($file); @@ -1280,7 +1293,43 @@ class Smarty extends Smarty_Internal_TemplateBase { { return Smarty_Internal_Utility::testInstall($this, $errors); } - + + /** + * Error Handler to mute expected messages + * + * @link http://php.net/set_error_handler + * @param integer $errno Error level + * @return boolean + */ + public static function mutingErrorHandler($errno) + { + // return false if $errno is not 0 and included in current error level + return (bool)($errno && $errno & error_reporting()); + } + + /** + * Enable error handler to mute expected messages + * + * @return void + */ + public static function muteExpectedErrors() + { + if (self::$error_muting) { + set_error_handler(array('Smarty', 'mutingErrorHandler')); + } + } + + /** + * Disable error handler muting expected messages + * + * @return void + */ + public static function unmuteExpectedErrors() + { + if (self::$error_muting) { + restore_error_handler(); + } + } } /** diff --git a/libs/sysplugins/smarty_internal_cacheresource_file.php b/libs/sysplugins/smarty_internal_cacheresource_file.php index a5cd9f8b..39c74ea7 100644 --- a/libs/sysplugins/smarty_internal_cacheresource_file.php +++ b/libs/sysplugins/smarty_internal_cacheresource_file.php @@ -61,7 +61,9 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource { $cached->lock_id = $_lock_dir.sha1($_cache_id.$_compile_id.$_template->source->uid).'.lock'; } $cached->filepath = $_cache_dir . $_cache_id . $_compile_id . $_filepath . '.' . basename($_source_file_path) . '.php'; + Smarty::muteExpectedErrors(); $cached->timestamp = @filemtime($cached->filepath); + Smarty::unmuteExpectedErrors(); $cached->exists = !!$cached->timestamp; } @@ -73,7 +75,9 @@ class Smarty_Internal_CacheResource_File extends Smarty_CacheResource { */ public function populateTimestamp(Smarty_Template_Cached $cached) { + Smarty::muteExpectedErrors(); $cached->timestamp = @filemtime($cached->filepath); + Smarty::unmuteExpectedErrors(); $cached->exists = !!$cached->timestamp; } diff --git a/libs/sysplugins/smarty_internal_data.php b/libs/sysplugins/smarty_internal_data.php index 09791152..0c40f540 100644 --- a/libs/sysplugins/smarty_internal_data.php +++ b/libs/sysplugins/smarty_internal_data.php @@ -174,6 +174,7 @@ class Smarty_Internal_Data { if (!isset($this->tpl_vars[$tpl_var])) { $this->tpl_vars[$tpl_var] = new Smarty_variable(); } + // FIXME u.tews what's this @silence doing here? if (!@is_array($this->tpl_vars[$tpl_var]->value)) { settype($this->tpl_vars[$tpl_var]->value, 'array'); } diff --git a/libs/sysplugins/smarty_internal_resource_file.php b/libs/sysplugins/smarty_internal_resource_file.php index 48b391d2..66370381 100644 --- a/libs/sysplugins/smarty_internal_resource_file.php +++ b/libs/sysplugins/smarty_internal_resource_file.php @@ -26,6 +26,7 @@ class Smarty_Internal_Resource_File extends Smarty_Resource { */ public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null) { + Smarty::muteExpectedErrors(); $source->filepath = $this->buildFilepath($source, $_template); if ($source->filepath !== false) { @@ -39,6 +40,7 @@ class Smarty_Internal_Resource_File extends Smarty_Resource { $source->exists = !!$source->timestamp; } } + Smarty::unmuteExpectedErrors(); } /** @@ -48,7 +50,9 @@ class Smarty_Internal_Resource_File extends Smarty_Resource { */ public function populateTimestamp(Smarty_Template_Source $source) { + Smarty::muteExpectedErrors(); $source->timestamp = @filemtime($source->filepath); + Smarty::unmuteExpectedErrors(); $source->exists = !!$source->timestamp; } diff --git a/libs/sysplugins/smarty_internal_resource_php.php b/libs/sysplugins/smarty_internal_resource_php.php index bfa74d05..9c79e28d 100644 --- a/libs/sysplugins/smarty_internal_resource_php.php +++ b/libs/sysplugins/smarty_internal_resource_php.php @@ -35,6 +35,7 @@ class Smarty_Internal_Resource_PHP extends Smarty_Resource_Uncompiled { */ public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null) { + Smarty::muteExpectedErrors(); $source->filepath = $this->buildFilepath($source, $_template); if ($source->filepath !== false) { @@ -48,6 +49,7 @@ class Smarty_Internal_Resource_PHP extends Smarty_Resource_Uncompiled { $source->exists = !!$source->timestamp; } } + Smarty::unmuteExpectedErrors(); } /** @@ -58,7 +60,9 @@ class Smarty_Internal_Resource_PHP extends Smarty_Resource_Uncompiled { */ public function populateTimestamp(Smarty_Template_Source $source) { + Smarty::muteExpectedErrors(); $source->timestamp = @filemtime($source->filepath); + Smarty::unmuteExpectedErrors(); $source->exists = !!$source->timestamp; } diff --git a/libs/sysplugins/smarty_internal_write_file.php b/libs/sysplugins/smarty_internal_write_file.php index 4e34335f..76715e4c 100644 --- a/libs/sysplugins/smarty_internal_write_file.php +++ b/libs/sysplugins/smarty_internal_write_file.php @@ -1,56 +1,74 @@ _file_perms !== null) { + $old_umask = umask(0); + } + + $_dirpath = dirname($_filepath); // if subdirs, create dir structure if ($_dirpath !== '.' && !file_exists($_dirpath)) { - mkdir($_dirpath, $smarty->_dir_perms, true); - } - // write to tmp file, then move to overt file lock race condition - $_tmp_file = tempnam($_dirpath, 'wrt'); + mkdir($_dirpath, $smarty->_dir_perms === null ? 0777 : $smarty->_dir_perms, true); + } - if (!($fd = @fopen($_tmp_file, 'wb'))) { - $_tmp_file = $_dirpath . DS . uniqid('wrt'); - if (!($fd = @fopen($_tmp_file, 'wb'))) { + // write to tmp file, then move to overt file lock race condition + $_tmp_file = $_dirpath . DS . uniqid('wrt'); + if (!file_put_contents($_tmp_file, $_contents)) { + error_reporting($_error_reporting); + Smarty::unmuteExpectedErrors(); throw new SmartyException("unable to write file {$_tmp_file}"); return false; - } - } - - fwrite($fd, $_contents); - fclose($fd); + } // remove original file - if (file_exists($_filepath)) - @unlink($_filepath); + unlink($_filepath); + // rename tmp file - rename($_tmp_file, $_filepath); - // set file permissions - chmod($_filepath, $smarty->_file_perms); - umask($old_umask); + $success = rename($_tmp_file, $_filepath); + if (!$success) { + error_reporting($_error_reporting); + Smarty::unmuteExpectedErrors(); + throw new SmartyException("unable to write file {$_filepath}"); + return false; + } + + if ($smarty->_file_perms !== null) { + // set file permissions + chmod($_filepath, $smarty->_file_perms); + umask($old_umask); + } + error_reporting($_error_reporting); + Smarty::unmuteExpectedErrors(); return true; - } -} + } + +} ?> \ No newline at end of file diff --git a/libs/sysplugins/smarty_resource.php b/libs/sysplugins/smarty_resource.php index 04fae95d..1cc6ddd4 100644 --- a/libs/sysplugins/smarty_resource.php +++ b/libs/sysplugins/smarty_resource.php @@ -422,7 +422,7 @@ abstract class Smarty_Resource { $resource_name = $template_resource; } } - + $resource = Smarty_Resource::load($smarty, $resource_type); $source = new Smarty_Template_Source($resource, $smarty, $template_resource, $resource_type, $resource_name); $resource->populate($source, $_template); @@ -609,7 +609,9 @@ class Smarty_Template_Source { $compiled = new Smarty_Template_Compiled($this); $this->handler->populateCompiledFilepath($compiled, $_template); + Smarty::muteExpectedErrors(); $compiled->timestamp = @filemtime($compiled->filepath); + Smarty::unmuteExpectedErrors(); $compiled->exists = !!$compiled->timestamp; // runtime cache