diff --git a/README b/README index c7215ab1..9304219b 100644 --- a/README +++ b/README @@ -120,7 +120,7 @@ $smarty->unregisterObject($object_name) $smarty->unregisterFilter($type, $function_name) $smarty->unregisterResource($resource_type) -$smarty->compileAllTemplates($extention = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null) +$smarty->compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null) $smarty->clearCompiledTemplate($resource_name = null, $compile_id = null, $exp_time = null) $smarty->testInstall() diff --git a/SMARTY_3.1_NOTES.txt b/SMARTY_3.1_NOTES.txt index e56e56f6..57709f0d 100644 --- a/SMARTY_3.1_NOTES.txt +++ b/SMARTY_3.1_NOTES.txt @@ -199,7 +199,7 @@ Relative paths are available with {include file="..."} and $smarty->fetch('./foo.tpl') cannot be relative to a template, an exception is thrown. - Adressing a specific $template_dir + Addressing a specific $template_dir Smarty 3.1 introduces the $template_dir index notation. $smarty->fetch('[foo]bar.tpl') and {include file="[foo]bar.tpl"} diff --git a/change_log.txt b/change_log.txt index 0abde7bd..a4a5e290 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,10 +1,43 @@ -==== Smarty-3.1.13 ===== +===== trunk ===== +27.06.2013 +- bugfix removed PHP 5.5 deprecated preg_replace /e option in modifier capitalize (forum topic 24389) + +17.06.2013 +- fixed spelling in sources and documentation (from smarty-developers forum Veres Lajos) +- enhancement added constant SMARTY::CLEAR_EXPIRED for the change of 26.05.2013 (forum topic 24310) +- bugfix added smarty_security.php to composer.json (Issue 135) + +26.05.2013 +- enhancement an expire_time of -1 in clearCache() and clearAllCache() will delete outdated cache files + by their individual cache_lifetime used at creation (forum topic 24310) + +21.05.2013 +- bugfix modifier strip_tags:true was compiled into wrong code (Forum Topic 24287) +- bugfix /n after ?> in Smarty.class.php did start output buffering (Issue 138) + +25.04.2013 +- bugfix escape and wordrap modifier could be compiled into wrong code when used in {nocache}{/nocache} + section but caching is disabled (Forum Topic 24260) + +05.04.2013 +- bugfix post filter must not run when compiling inheritance child blocks (Forum Topic 24094) +- bugfix after the fix for Issue #130 compiler exceptions got double escaped (Forum Topic 24199) + +28.02.2013 +- bugfix nocache blocks could be lost when using CACHING_LIFETIME_SAVED (Issue #133) +- bugfix Compile ID gets nulled when compiling child blocks (Issue #134) + + +24.01.2013 +- bugfix wrong tag type in smarty_internal_templatecompilerbase.php could cause wrong plugin search order (Forum Topic 24028) + +===== Smarty-3.1.13 ===== 13.01.2013 - enhancement allow to disable exception message escaping by SmartyException::$escape = false; (Issue #130) 09.01.2013 -- bugfix compilation did fail when a prefilter did modify an {extends} tag (Forum Topic 23966) +- bugfix compilation did fail when a prefilter did modify an {extends} tag c - bugfix template inheritance could fail if nested {block} tags in childs did contain {$smarty.block.child} (Issue #127) - bugfix template inheritance could fail if {block} tags in childs did have similar name as used plugins (Issue #128) - added abstract method declaration doCompile() in Smarty_Internal_TemplateCompilerBase (Forum Topic 23969) @@ -418,7 +451,7 @@ 03/09/2011 - bugfix createTemplate() must default to cache_id and compile_id of Smarty object - bugfix Smarty_CacheResource_KeyValueStore must include $source->uid in cache filepath to keep templates with same - name but different folders seperated + name but different folders separated - added cacheresource.apc.php example in demo folder 02/09/2011 @@ -609,7 +642,7 @@ - changed ./ and ../ behaviour 14/02/2011 -- added {block ... hide} option to supress block if no child is defined +- added {block ... hide} option to suppress block if no child is defined 13/02/2011 - update handling of recursive subtemplate calls @@ -723,7 +756,7 @@ - bugfix on compiler object destruction. compiler_object property was by mistake unset. 09/03/2011 --bugfix a variable filter should run before modifers on an output tag (see change of 23/07/2010) +-bugfix a variable filter should run before modifiers on an output tag (see change of 23/07/2010) 08/03/2011 - bugfix loading config file without section should load only defaults @@ -1027,10 +1060,10 @@ request_use_auto_globals - bugfix passing scope attributes in doublequoted strings did not work at {include} {assign} and {append} 25/07/2010 -- another bugfix of change from 23/07/2010 when compiling modifer +- another bugfix of change from 23/07/2010 when compiling modifier 24/07/2010 -- bugfix of change from 23/07/2010 when compiling modifer +- bugfix of change from 23/07/2010 when compiling modifier 23/07/2010 - changed execution order. A variable filter does now run before modifiers on output of variables @@ -1337,7 +1370,7 @@ request_use_auto_globals - bugfix on {if} tags 01/12/2010 -- changed back modifer handling in parser. Some restrictions still apply: +- changed back modifier handling in parser. Some restrictions still apply: if modifiers are used in side {if...} expression or in mathematical expressions parentheses must be used. - bugfix the {function..} tag did not accept the name attribute in double quotes @@ -1949,7 +1982,7 @@ NOTICE: existing compiled template and cache files must be deleted - fixed exceptions in function plugins - fixed notice error in Smarty.class.php - allow chained objects to span multiple lines -- fixed error in modifers +- fixed error in modifiers 03/20/2009 - moved /plugins folder into /libs folder @@ -1957,7 +1990,7 @@ NOTICE: existing compiled template and cache files must be deleted - autoappend a directory separator if the xxxxx_dir definition have no trailing one 03/19/2009 -- allow array definition as modifer parameter +- allow array definition as modifier parameter - changed modifier to use multi byte string funktions. 03/17/2009 diff --git a/demo/plugins/resource.mysqls.php b/demo/plugins/resource.mysqls.php index f9fe1c2f..e22bed0a 100644 --- a/demo/plugins/resource.mysqls.php +++ b/demo/plugins/resource.mysqls.php @@ -7,7 +7,7 @@ * MySQL as the storage resource for Smarty's templates and configs. * * Note that this MySQL implementation fetches the source and timestamps in - * a single database query, instead of two seperate like resource.mysql.php does. + * a single database query, instead of two separate like resource.mysql.php does. * * Table definition: *
CREATE TABLE IF NOT EXISTS `templates` (
diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php
index af99a23c..6c452fde 100644
--- a/libs/Smarty.class.php
+++ b/libs/Smarty.class.php
@@ -128,6 +128,11 @@ class Smarty extends Smarty_Internal_TemplateBase {
     const CACHING_OFF = 0;
     const CACHING_LIFETIME_CURRENT = 1;
     const CACHING_LIFETIME_SAVED = 2;
+    /**
+     * define constant for clearing cache files be saved expiration datees
+     */
+    const CLEAR_EXPIRED = -1; 
+
     /**
      * define compile check modes
      */
@@ -1323,9 +1328,9 @@ class Smarty extends Smarty_Internal_TemplateBase {
      * @param int $max_errors
      * @return integer number of template files recompiled
      */
-    public function compileAllTemplates($extention = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
+    public function compileAllTemplates($extension = '.tpl', $force_compile = false, $time_limit = 0, $max_errors = null)
     {
-        return Smarty_Internal_Utility::compileAllTemplates($extention, $force_compile, $time_limit, $max_errors, $this);
+        return Smarty_Internal_Utility::compileAllTemplates($extension, $force_compile, $time_limit, $max_errors, $this);
     }
 
     /**
@@ -1337,9 +1342,9 @@ class Smarty extends Smarty_Internal_TemplateBase {
      * @param int $max_errors
      * @return integer number of template files recompiled
      */
-    public function compileAllConfig($extention = '.conf', $force_compile = false, $time_limit = 0, $max_errors = null)
+    public function compileAllConfig($extension = '.conf', $force_compile = false, $time_limit = 0, $max_errors = null)
     {
-        return Smarty_Internal_Utility::compileAllConfig($extention, $force_compile, $time_limit, $max_errors, $this);
+        return Smarty_Internal_Utility::compileAllConfig($extension, $force_compile, $time_limit, $max_errors, $this);
     }
 
     /**
@@ -1525,4 +1530,4 @@ function smartyAutoload($class)
     }
 }
 
-?>
+?>
\ No newline at end of file
diff --git a/libs/plugins/modifier.capitalize.php b/libs/plugins/modifier.capitalize.php
index a78e3632..580e3d5c 100644
--- a/libs/plugins/modifier.capitalize.php
+++ b/libs/plugins/modifier.capitalize.php
@@ -30,7 +30,7 @@ function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = fals
             $upper_string = mb_convert_case( $string, MB_CASE_TITLE, Smarty::$_CHARSET );
         } else {
             // uppercase word breaks
-            $upper_string = preg_replace("!(^|[^\p{L}'])([\p{Ll}])!eS" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').mb_convert_case(stripslashes('\\2'),MB_CASE_UPPER, '" . addslashes(Smarty::$_CHARSET) . "')", $string);
+            $upper_string = preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER, create_function ('$matches', 'return stripslashes($matches[1]).mb_convert_case(stripslashes($matches[2]),MB_CASE_UPPER, "' . addslashes(Smarty::$_CHARSET) . '");'), $string);
         }
         // check uc_digits case
         if (!$uc_digits) {
@@ -40,7 +40,7 @@ function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = fals
                 }
             } 
         }
-        $upper_string = preg_replace("!((^|\s)['\"])(\w)!e" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').mb_convert_case(stripslashes('\\3'),MB_CASE_UPPER, '" . addslashes(Smarty::$_CHARSET) . "')", $upper_string);
+        $upper_string = preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, create_function ('$matches', 'return stripslashes($matches[1]).mb_convert_case(stripslashes($matches[3]),MB_CASE_UPPER, "' . addslashes(Smarty::$_CHARSET) . '");'), $upper_string);
         return $upper_string;
     }
     
@@ -49,7 +49,7 @@ function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = fals
         $string = strtolower($string);
     }
     // uppercase (including hyphenated words)
-    $upper_string = preg_replace("!(^|[^\p{L}'])([\p{Ll}])!eS" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').ucfirst(stripslashes('\\2'))", $string); 
+    $upper_string = preg_replace_callback("!(^|[^\p{L}'])([\p{Ll}])!S" . Smarty::$_UTF8_MODIFIER, create_function ('$matches', 'return stripslashes($matches[1]).ucfirst(stripslashes($matches[2]));'), $string); 
     // check uc_digits case
     if (!$uc_digits) {
         if (preg_match_all("!\b([\p{L}]*[\p{N}]+[\p{L}]*)\b!" . Smarty::$_UTF8_MODIFIER, $string, $matches, PREG_OFFSET_CAPTURE)) {
@@ -58,7 +58,7 @@ function smarty_modifier_capitalize($string, $uc_digits = false, $lc_rest = fals
             }
         } 
     }
-    $upper_string = preg_replace("!((^|\s)['\"])(\w)!e" . Smarty::$_UTF8_MODIFIER, "stripslashes('\\1').strtoupper(stripslashes('\\3'))", $upper_string);
+    $upper_string = preg_replace_callback("!((^|\s)['\"])(\w)!" . Smarty::$_UTF8_MODIFIER, create_function ('$matches', 'return stripslashes($matches[1]).ucfirst(stripslashes($matches[3]));'), $upper_string);
     return $upper_string;
 } 
 
diff --git a/libs/plugins/modifiercompiler.escape.php b/libs/plugins/modifiercompiler.escape.php
index f50028bd..f5b4f433 100644
--- a/libs/plugins/modifiercompiler.escape.php
+++ b/libs/plugins/modifiercompiler.escape.php
@@ -112,7 +112,7 @@ function smarty_modifiercompiler_escape($params, $compiler)
     }
 
     // could not optimize |escape call, so fallback to regular plugin
-    if ($compiler->tag_nocache | $compiler->nocache) {
+    if ($compiler->template->caching && ($compiler->tag_nocache | $compiler->nocache)) {
         $compiler->template->required_plugins['nocache']['escape']['modifier']['file'] = SMARTY_PLUGINS_DIR .'modifier.escape.php';
         $compiler->template->required_plugins['nocache']['escape']['modifier']['function'] = 'smarty_modifier_escape';
     } else {
diff --git a/libs/plugins/modifiercompiler.strip_tags.php b/libs/plugins/modifiercompiler.strip_tags.php
index 296a3a2d..68a9e75d 100644
--- a/libs/plugins/modifiercompiler.strip_tags.php
+++ b/libs/plugins/modifiercompiler.strip_tags.php
@@ -20,14 +20,9 @@
  */
 function smarty_modifiercompiler_strip_tags($params, $compiler)
 {
-   if (!isset($params[1])) {
-        $params[1] = true;
-    }
-    if ($params[1] === true) {
-        return "preg_replace('!<[^>]*?>!', ' ', {$params[0]})";
+ if (!isset($params[1]) || $params[1] === true ||  trim($params[1],'"') == 'true') {
+         return "preg_replace('!<[^>]*?>!', ' ', {$params[0]})";
     } else {
         return 'strip_tags(' . $params[0] . ')';
     }
 }
-
-?>
\ No newline at end of file
diff --git a/libs/plugins/modifiercompiler.wordwrap.php b/libs/plugins/modifiercompiler.wordwrap.php
index f6845ad3..9f21e224 100644
--- a/libs/plugins/modifiercompiler.wordwrap.php
+++ b/libs/plugins/modifiercompiler.wordwrap.php
@@ -31,7 +31,7 @@ function smarty_modifiercompiler_wordwrap($params, $compiler)
     } 
     $function = 'wordwrap';
     if (Smarty::$_MBSTRING) {
-        if ($compiler->tag_nocache | $compiler->nocache) {
+    if ($compiler->template->caching && ($compiler->tag_nocache | $compiler->nocache)) {
             $compiler->template->required_plugins['nocache']['wordwrap']['modifier']['file'] = SMARTY_PLUGINS_DIR .'shared.mb_wordwrap.php';
             $compiler->template->required_plugins['nocache']['wordwrap']['modifier']['function'] = 'smarty_mb_wordwrap';
         } else {
diff --git a/libs/sysplugins/smarty_cacheresource.php b/libs/sysplugins/smarty_cacheresource.php
index ca18add5..a6852998 100644
--- a/libs/sysplugins/smarty_cacheresource.php
+++ b/libs/sysplugins/smarty_cacheresource.php
@@ -224,7 +224,7 @@ class Smarty_Template_Cached {
     public $timestamp = false;
 
     /**
-    * Source Existance
+    * Source Existence
     * @var boolean
     */
     public $exists = false;
diff --git a/libs/sysplugins/smarty_internal_cacheresource_file.php b/libs/sysplugins/smarty_internal_cacheresource_file.php
index 04194b39..fca897d9 100644
--- a/libs/sysplugins/smarty_internal_cacheresource_file.php
+++ b/libs/sysplugins/smarty_internal_cacheresource_file.php
@@ -1,266 +1,275 @@
 source->filepath);
-        $_cache_id = isset($_template->cache_id) ? preg_replace('![^\w\|]+!', '_', $_template->cache_id) : null;
-        $_compile_id = isset($_template->compile_id) ? preg_replace('![^\w\|]+!', '_', $_template->compile_id) : null;
-        $_filepath = $_template->source->uid;
-        // if use_sub_dirs, break file into directories
-        if ($_template->smarty->use_sub_dirs) {
-            $_filepath = substr($_filepath, 0, 2) . DS
+    * This class does contain all necessary methods for the HTML cache on file system
+    *
+    * Implements the file system as resource for the HTML cache Version ussing nocache inserts.
+    *
+    * @package Smarty
+    * @subpackage Cacher
+    */
+    class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
+
+        /**
+        * populate Cached Object with meta data from Resource
+        *
+        * @param Smarty_Template_Cached   $cached    cached object
+        * @param Smarty_Internal_Template $_template template object
+        * @return void
+        */
+        public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template)
+        {
+            $_source_file_path = str_replace(':', '.', $_template->source->filepath);
+            $_cache_id = isset($_template->cache_id) ? preg_replace('![^\w\|]+!', '_', $_template->cache_id) : null;
+            $_compile_id = isset($_template->compile_id) ? preg_replace('![^\w\|]+!', '_', $_template->compile_id) : null;
+            $_filepath = $_template->source->uid;
+            // if use_sub_dirs, break file into directories
+            if ($_template->smarty->use_sub_dirs) {
+                $_filepath = substr($_filepath, 0, 2) . DS
                 . substr($_filepath, 2, 2) . DS
                 . substr($_filepath, 4, 2) . DS
                 . $_filepath;
-        }
-        $_compile_dir_sep = $_template->smarty->use_sub_dirs ? DS : '^';
-        if (isset($_cache_id)) {
-            $_cache_id = str_replace('|', $_compile_dir_sep, $_cache_id) . $_compile_dir_sep;
-        } else {
-            $_cache_id = '';
-        }
-        if (isset($_compile_id)) {
-            $_compile_id = $_compile_id . $_compile_dir_sep;
-        } else {
-            $_compile_id = '';
-        }
-        $_cache_dir = $_template->smarty->getCacheDir();
-        if ($_template->smarty->cache_locking) {
-            // create locking file name
-            // relative file name?
-            if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_cache_dir)) {
-                $_lock_dir = rtrim(getcwd(), '/\\') . DS . $_cache_dir;
+            }
+            $_compile_dir_sep = $_template->smarty->use_sub_dirs ? DS : '^';
+            if (isset($_cache_id)) {
+                $_cache_id = str_replace('|', $_compile_dir_sep, $_cache_id) . $_compile_dir_sep;
             } else {
-                $_lock_dir = $_cache_dir;
+                $_cache_id = '';
             }
-            $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';
-        $cached->timestamp = @filemtime($cached->filepath);
-        $cached->exists = !!$cached->timestamp;
-    }
-
-    /**
-     * populate Cached Object with timestamp and exists from Resource
-     *
-     * @param Smarty_Template_Cached $cached cached object
-     * @return void
-     */
-    public function populateTimestamp(Smarty_Template_Cached $cached)
-    {
-        $cached->timestamp = @filemtime($cached->filepath);
-        $cached->exists = !!$cached->timestamp;
-    }
-
-    /**
-     * Read the cached template and process its header
-     *
-     * @param Smarty_Internal_Template $_template template object
-     * @param Smarty_Template_Cached $cached cached object
-     * @return booelan true or false if the cached content does not exist
-     */
-    public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached=null)
-    {
-        $_smarty_tpl = $_template;
-        return @include $_template->cached->filepath;
-    }
-
-    /**
-     * Write the rendered template output to cache
-     *
-     * @param Smarty_Internal_Template $_template template object
-     * @param string                   $content   content to cache
-     * @return boolean success
-     */
-    public function writeCachedContent(Smarty_Internal_Template $_template, $content)
-    {
-        if (Smarty_Internal_Write_File::writeFile($_template->cached->filepath, $content, $_template->smarty) === true) {
-            $_template->cached->timestamp = @filemtime($_template->cached->filepath);
-            $_template->cached->exists = !!$_template->cached->timestamp;
-            if ($_template->cached->exists) {
-                return true;
-            }
-        }
-        return false;
-    }
-
-    /**
-     * Empty cache
-     *
-     * @param Smarty_Internal_Template $_template template object
-     * @param integer                  $exp_time  expiration time (number of seconds, not timestamp)
-     * @return integer number of cache files deleted
-     */
-    public function clearAll(Smarty $smarty, $exp_time = null)
-    {
-        return $this->clear($smarty, null, null, null, $exp_time);
-    }
-
-    /**
-     * Empty cache for a specific template
-     *
-     * @param Smarty  $_template     template object
-     * @param string  $resource_name template name
-     * @param string  $cache_id      cache id
-     * @param string  $compile_id    compile id
-     * @param integer $exp_time      expiration time (number of seconds, not timestamp)
-     * @return integer number of cache files deleted
-    */
-    public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time)
-    {
-        $_cache_id = isset($cache_id) ? preg_replace('![^\w\|]+!', '_', $cache_id) : null;
-        $_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null;
-        $_dir_sep = $smarty->use_sub_dirs ? '/' : '^';
-        $_compile_id_offset = $smarty->use_sub_dirs ? 3 : 0;
-        $_dir = $smarty->getCacheDir();
-        $_dir_length = strlen($_dir);
-        if (isset($_cache_id)) {
-            $_cache_id_parts = explode('|', $_cache_id);
-            $_cache_id_parts_count = count($_cache_id_parts);
-            if ($smarty->use_sub_dirs) {
-                foreach ($_cache_id_parts as $id_part) {
-                    $_dir .= $id_part . DS;
-                }
-            }
-        }
-        if (isset($resource_name)) {
-            $_save_stat = $smarty->caching;
-            $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 ($smarty->allow_ambiguous_resources) {
-                $_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id;
+            if (isset($_compile_id)) {
+                $_compile_id = $_compile_id . $_compile_dir_sep;
             } else {
-                $_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id;
+                $_compile_id = '';
             }
-            if (isset($_templateId[150])) {
-                $_templateId = sha1($_templateId);
-            }
-            unset($smarty->template_objects[$_templateId]);
-
-            if ($tpl->source->exists) {
-                $_resourcename_parts = basename(str_replace('^', '/', $tpl->cached->filepath));
-            } else {
-                return 0;
-            }
-        }
-        $_count = 0;
-        $_time = time();
-        if (file_exists($_dir)) {
-            $_cacheDirs = new RecursiveDirectoryIterator($_dir);
-            $_cache = new RecursiveIteratorIterator($_cacheDirs, RecursiveIteratorIterator::CHILD_FIRST);
-            foreach ($_cache as $_file) {
-                if (substr(basename($_file->getPathname()),0,1) == '.' || strpos($_file, '.svn') !== false) continue;
-                // directory ?
-                if ($_file->isDir()) {
-                    if (!$_cache->isDot()) {
-                        // delete folder if empty
-                        @rmdir($_file->getPathname());
-                    }
+            $_cache_dir = $_template->smarty->getCacheDir();
+            if ($_template->smarty->cache_locking) {
+                // create locking file name
+                // relative file name?
+                if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_cache_dir)) {
+                    $_lock_dir = rtrim(getcwd(), '/\\') . DS . $_cache_dir;
                 } else {
-                    $_parts = explode($_dir_sep, str_replace('\\', '/', substr((string)$_file, $_dir_length)));
-                    $_parts_count = count($_parts);
-                    // check name
-                    if (isset($resource_name)) {
-                        if ($_parts[$_parts_count-1] != $_resourcename_parts) {
-                            continue;
-                        }
-                    }
-                    // check compile id
-                    if (isset($_compile_id) && (!isset($_parts[$_parts_count-2 - $_compile_id_offset]) || $_parts[$_parts_count-2 - $_compile_id_offset] != $_compile_id)) {
-                        continue;
-                    }
-                    // check cache id
-                    if (isset($_cache_id)) {
-                        // count of cache id parts
-                        $_parts_count = (isset($_compile_id)) ? $_parts_count - 2 - $_compile_id_offset : $_parts_count - 1 - $_compile_id_offset;
-                        if ($_parts_count < $_cache_id_parts_count) {
-                            continue;
-                        }
-                        for ($i = 0; $i < $_cache_id_parts_count; $i++) {
-                            if ($_parts[$i] != $_cache_id_parts[$i]) continue 2;
-                        }
-                    }
-                    // expired ?
-                    if (isset($exp_time) && $_time - @filemtime($_file) < $exp_time) {
-                        continue;
-                    }
-                    $_count += @unlink((string) $_file) ? 1 : 0;
+                    $_lock_dir = $_cache_dir;
+                }
+                $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';
+            $cached->timestamp = @filemtime($cached->filepath);
+            $cached->exists = !!$cached->timestamp;
+        }
+
+        /**
+        * populate Cached Object with timestamp and exists from Resource
+        *
+        * @param Smarty_Template_Cached $cached cached object
+        * @return void
+        */
+        public function populateTimestamp(Smarty_Template_Cached $cached)
+        {
+            $cached->timestamp = @filemtime($cached->filepath);
+            $cached->exists = !!$cached->timestamp;
+        }
+
+        /**
+        * Read the cached template and process its header
+        *
+        * @param Smarty_Internal_Template $_template template object
+        * @param Smarty_Template_Cached $cached cached object
+        * @return booelan true or false if the cached content does not exist
+        */
+        public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached=null)
+        {
+            $_smarty_tpl = $_template;
+            return @include $_template->cached->filepath;
+        }
+
+        /**
+        * Write the rendered template output to cache
+        *
+        * @param Smarty_Internal_Template $_template template object
+        * @param string                   $content   content to cache
+        * @return boolean success
+        */
+        public function writeCachedContent(Smarty_Internal_Template $_template, $content)
+        {
+            if (Smarty_Internal_Write_File::writeFile($_template->cached->filepath, $content, $_template->smarty) === true) {
+                $_template->cached->timestamp = @filemtime($_template->cached->filepath);
+                $_template->cached->exists = !!$_template->cached->timestamp;
+                if ($_template->cached->exists) {
+                    return true;
                 }
             }
+            return false;
         }
-        return $_count;
-    }
 
-    /**
-     * Check is cache is locked for this template
-     *
-     * @param Smarty $smarty Smarty object
-     * @param Smarty_Template_Cached $cached cached object
-     * @return booelan true or false if cache is locked
-     */
-    public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached)
-    {
-        if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
-            clearstatcache(true, $cached->lock_id);
-        } else {
-            clearstatcache();
+        /**
+        * Empty cache
+        *
+        * @param Smarty_Internal_Template $_template template object
+        * @param integer                  $exp_time  expiration time (number of seconds, not timestamp)
+        * @return integer number of cache files deleted
+        */
+        public function clearAll(Smarty $smarty, $exp_time = null)
+        {
+            return $this->clear($smarty, null, null, null, $exp_time);
         }
-        $t = @filemtime($cached->lock_id);
-        return $t && (time() - $t < $smarty->locking_timeout);
-    }
 
-    /**
-     * Lock cache for this template
-     *
-     * @param Smarty $smarty Smarty object
-     * @param Smarty_Template_Cached $cached cached object
-     */
-    public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached)
-    {
-        $cached->is_locked = true;
-        touch($cached->lock_id);
-    }
+        /**
+        * Empty cache for a specific template
+        *
+        * @param Smarty  $_template     template object
+        * @param string  $resource_name template name
+        * @param string  $cache_id      cache id
+        * @param string  $compile_id    compile id
+        * @param integer $exp_time      expiration time (number of seconds, not timestamp)
+        * @return integer number of cache files deleted
+        */
+        public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time)
+        {
+            $_cache_id = isset($cache_id) ? preg_replace('![^\w\|]+!', '_', $cache_id) : null;
+            $_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null;
+            $_dir_sep = $smarty->use_sub_dirs ? '/' : '^';
+            $_compile_id_offset = $smarty->use_sub_dirs ? 3 : 0;
+            $_dir = $smarty->getCacheDir();
+            $_dir_length = strlen($_dir);
+            if (isset($_cache_id)) {
+                $_cache_id_parts = explode('|', $_cache_id);
+                $_cache_id_parts_count = count($_cache_id_parts);
+                if ($smarty->use_sub_dirs) {
+                    foreach ($_cache_id_parts as $id_part) {
+                        $_dir .= $id_part . DS;
+                    }
+                }
+            }
+            if (isset($resource_name)) {
+                $_save_stat = $smarty->caching;
+                $smarty->caching = true;
+                $tpl = new $smarty->template_class($resource_name, $smarty);
+                $smarty->caching = $_save_stat;
 
-    /**
-     * Unlock cache for this template
-     *
-     * @param Smarty $smarty Smarty object
-     * @param Smarty_Template_Cached $cached cached object
-     */
-    public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
-    {
-        $cached->is_locked = false;
-        @unlink($cached->lock_id);
+                // remove from template cache
+                $tpl->source; // have the template registered before unset()
+                if ($smarty->allow_ambiguous_resources) {
+                    $_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id;
+                } else {
+                    $_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id;
+                }
+                if (isset($_templateId[150])) {
+                    $_templateId = sha1($_templateId);
+                }
+                unset($smarty->template_objects[$_templateId]);
+
+                if ($tpl->source->exists) {
+                    $_resourcename_parts = basename(str_replace('^', '/', $tpl->cached->filepath));
+                } else {
+                    return 0;
+                }
+            }
+            $_count = 0;
+            $_time = time();
+            if (file_exists($_dir)) {
+                $_cacheDirs = new RecursiveDirectoryIterator($_dir);
+                $_cache = new RecursiveIteratorIterator($_cacheDirs, RecursiveIteratorIterator::CHILD_FIRST);
+                foreach ($_cache as $_file) {
+                    if (substr(basename($_file->getPathname()),0,1) == '.' || strpos($_file, '.svn') !== false) continue;
+                    // directory ?
+                    if ($_file->isDir()) {
+                        if (!$_cache->isDot()) {
+                            // delete folder if empty
+                            @rmdir($_file->getPathname());
+                        }
+                    } else {
+                        $_parts = explode($_dir_sep, str_replace('\\', '/', substr((string)$_file, $_dir_length)));
+                        $_parts_count = count($_parts);
+                        // check name
+                        if (isset($resource_name)) {
+                            if ($_parts[$_parts_count-1] != $_resourcename_parts) {
+                                continue;
+                            }
+                        }
+                        // check compile id
+                        if (isset($_compile_id) && (!isset($_parts[$_parts_count-2 - $_compile_id_offset]) || $_parts[$_parts_count-2 - $_compile_id_offset] != $_compile_id)) {
+                            continue;
+                        }
+                        // check cache id
+                        if (isset($_cache_id)) {
+                            // count of cache id parts
+                            $_parts_count = (isset($_compile_id)) ? $_parts_count - 2 - $_compile_id_offset : $_parts_count - 1 - $_compile_id_offset;
+                            if ($_parts_count < $_cache_id_parts_count) {
+                                continue;
+                            }
+                            for ($i = 0; $i < $_cache_id_parts_count; $i++) {
+                                if ($_parts[$i] != $_cache_id_parts[$i]) continue 2;
+                            }
+                        }
+                        // expired ? 
+                        if  (isset($exp_time)) {
+                            if ($exp_time < 0) {
+                                preg_match('#\'cache_lifetime\' =>\s*(\d*)#', file_get_contents($_file), $match); 
+                                if ($_time < (@filemtime($_file) + $match[1])) { 
+                                    continue; 
+                                }
+                            } else {
+                                if ($_time - @filemtime($_file) < $exp_time) {
+                                    continue;
+                                } 
+                            }
+                        }
+                        $_count += @unlink((string) $_file) ? 1 : 0;
+                    }
+                }
+            }
+            return $_count;
+        }
+
+        /**
+        * Check is cache is locked for this template
+        *
+        * @param Smarty $smarty Smarty object
+        * @param Smarty_Template_Cached $cached cached object
+        * @return booelan true or false if cache is locked
+        */
+        public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached)
+        {
+            if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
+                clearstatcache(true, $cached->lock_id);
+            } else {
+                clearstatcache();
+            }
+            $t = @filemtime($cached->lock_id);
+            return $t && (time() - $t < $smarty->locking_timeout);
+        }
+
+        /**
+        * Lock cache for this template
+        *
+        * @param Smarty $smarty Smarty object
+        * @param Smarty_Template_Cached $cached cached object
+        */
+        public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached)
+        {
+            $cached->is_locked = true;
+            touch($cached->lock_id);
+        }
+
+        /**
+        * Unlock cache for this template
+        *
+        * @param Smarty $smarty Smarty object
+        * @param Smarty_Template_Cached $cached cached object
+        */
+        public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
+        {
+            $cached->is_locked = false;
+            @unlink($cached->lock_id);
+        }
     }
-}
 
 ?>
\ No newline at end of file
diff --git a/libs/sysplugins/smarty_internal_compile_block.php b/libs/sysplugins/smarty_internal_compile_block.php
index f760e551..847b04a9 100644
--- a/libs/sysplugins/smarty_internal_compile_block.php
+++ b/libs/sysplugins/smarty_internal_compile_block.php
@@ -84,7 +84,7 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
             $al = '';
         }
         if (0 == preg_match("!({$_ldl}{$al}block\s+)(name=)?(\w+|'.*'|\".*\")(\s*?)?((append|prepend|nocache)?(\s*)?(hide)?)?(\s*{$_rdl})!", $block_tag, $_match)) {
-            $error_text = 'Syntax Error in template "' . $template->source->filepath . '"   "' . htmlspecialchars($block_tag) . '" illegal options';
+            $error_text = 'Syntax Error in template "' . $template->source->filepath . '"   "' . $block_tag . '" illegal options';
             throw new SmartyCompilerException($error_text);
         } else {
             $_name = trim($_match[3], '\'"');
@@ -179,7 +179,7 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
             return '';
         }
         $_tpl = new Smarty_Internal_template('string:' . $compiler->template->block_data[$_name]['source'], $compiler->smarty, $compiler->template, $compiler->template->cache_id,
-                        $compiler->template->compile_id = null, $compiler->template->caching, $compiler->template->cache_lifetime);
+                        $compiler->template->compile_id, $compiler->template->caching, $compiler->template->cache_lifetime);
         $_tpl->variable_filters = $compiler->template->variable_filters;
         $_tpl->properties['nocache_hash'] = $compiler->template->properties['nocache_hash'];
         $_tpl->source->filepath = $compiler->template->block_data[$_name]['file'];
@@ -190,6 +190,7 @@ class Smarty_Internal_Compile_Block extends Smarty_Internal_CompileBase {
             $_tpl->compiler->forceNocache = 1;
         }
         $_tpl->compiler->suppressHeader = true;
+        $_tpl->compiler->suppressFilter = true;
         $_tpl->compiler->suppressTemplatePropertyHeader = true;
         $_tpl->compiler->suppressMergedTemplates = true;
         if (strpos($compiler->template->block_data[$_name]['source'], '%%%%SMARTY_PARENT%%%%') !== false) {
diff --git a/libs/sysplugins/smarty_internal_template.php b/libs/sysplugins/smarty_internal_template.php
index 29017edb..b6dd87fc 100644
--- a/libs/sysplugins/smarty_internal_template.php
+++ b/libs/sysplugins/smarty_internal_template.php
@@ -467,10 +467,15 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase {
             }
         }
         if ($cache) {
+            // CACHING_LIFETIME_SAVED cache expiry has to be validated here since otherwise we'd define the unifunc
+            if ($this->caching === Smarty::CACHING_LIFETIME_SAVED &&
+                $this->properties['cache_lifetime'] >= 0 &&
+                (time() > ($this->cached->timestamp + $this->properties['cache_lifetime']))) {
+                $is_valid = false;
+            }
             $this->cached->valid = $is_valid;
         } else {
-            $this->mustCompile = !$is_valid;
-        }
+            $this->mustCompile = !$is_valid;        }
         // store data in reusable Smarty_Template_Compiled
         if (!$cache) {
             $this->compiled->_properties = $properties;
diff --git a/libs/sysplugins/smarty_internal_templatecompilerbase.php b/libs/sysplugins/smarty_internal_templatecompilerbase.php
index 11fc2144..8b5140cd 100644
--- a/libs/sysplugins/smarty_internal_templatecompilerbase.php
+++ b/libs/sysplugins/smarty_internal_templatecompilerbase.php
@@ -106,6 +106,12 @@ abstract class Smarty_Internal_TemplateCompilerBase {
      */
     public $suppressTemplatePropertyHeader = false;
 
+    /**
+     * suppress pre and post filter
+     * @var bool
+     */
+    public $suppressFilter = false;
+
     /**
      * flag if compiled template file shall we written
      * @var bool
@@ -184,7 +190,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
             // get template source
             $_content = $template->source->content;
             // run prefilter if required
-            if (isset($this->smarty->autoload_filters['pre']) || isset($this->smarty->registered_filters['pre'])) {
+            if ((isset($this->smarty->autoload_filters['pre']) || isset($this->smarty->registered_filters['pre'])) && !$this->suppressFilter) {
                 $_content = Smarty_Internal_Filter_Handler::runFilter('pre', $_content, $template);
             }
             // on empty template just return header
@@ -209,13 +215,9 @@ abstract class Smarty_Internal_TemplateCompilerBase {
             foreach ($this->merged_templates as $code) {
                 $merged_code .= $code;
             }
-            // run postfilter if required on merged code
-            if (isset($this->smarty->autoload_filters['post']) || isset($this->smarty->registered_filters['post'])) {
-                $merged_code = Smarty_Internal_Filter_Handler::runFilter('post', $merged_code, $template);
-            }
         }
         // run postfilter if required on compiled template code
-        if (isset($this->smarty->autoload_filters['post']) || isset($this->smarty->registered_filters['post'])) {
+        if ((isset($this->smarty->autoload_filters['post']) || isset($this->smarty->registered_filters['post'])) && !$this->suppressFilter) {
             $_compiled_code = Smarty_Internal_Filter_Handler::runFilter('post', $_compiled_code, $template);
         }
         if ($this->suppressTemplatePropertyHeader) {
@@ -331,7 +333,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
                 }
                 // check plugins from plugins folder
                 foreach ($this->smarty->plugin_search_order as $plugin_type) {
-                    if ($plugin_type == Smarty::PLUGIN_BLOCK && $this->smarty->loadPlugin('smarty_compiler_' . $tag) && (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this))) {
+                    if ($plugin_type == Smarty::PLUGIN_COMPILER && $this->smarty->loadPlugin('smarty_compiler_' . $tag) && (!isset($this->smarty->security_policy) || $this->smarty->security_policy->isTrustedTag($tag, $this))) {
                         $plugin = 'smarty_compiler_' . $tag;
                         if (is_callable($plugin)) {
                             // convert arguments format for old compiler plugins
@@ -605,7 +607,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
                 $_output = addcslashes($content,'\'\\');
                 $_output = str_replace("^#^", "'", $_output);
                 $_output = "nocache_hash}%%*/" . $_output . "/*/%%SmartyNocache:{$this->nocache_hash}%%*/';?>\n";
-                // make sure we include modifer plugins for nocache code
+                // make sure we include modifier plugins for nocache code
                 foreach ($this->modifier_plugins as $plugin_name => $dummy) {
                     if (isset($this->template->required_plugins['compiled'][$plugin_name]['modifier'])) {
                         $this->template->required_plugins['nocache'][$plugin_name]['modifier'] = $this->template->required_plugins['compiled'][$plugin_name]['modifier'];
@@ -641,7 +643,7 @@ abstract class Smarty_Internal_TemplateCompilerBase {
             $line = $this->lex->line;
         }
         $match = preg_split("/\n/", $this->lex->data);
-        $error_text = 'Syntax Error in template "' . $this->template->source->filepath . '"  on line ' . $line . ' "' . htmlspecialchars(trim(preg_replace('![\t\r\n]+!', ' ', $match[$line - 1]))) . '" ';
+        $error_text = 'Syntax Error in template "' . $this->template->source->filepath . '"  on line ' . $line . ' "' . trim(preg_replace('![\t\r\n]+!', ' ', $match[$line - 1])) . '" ';
         if (isset($args)) {
             // individual error message
             $error_text .= $args;
diff --git a/libs/sysplugins/smarty_internal_utility.php b/libs/sysplugins/smarty_internal_utility.php
index f19ca01f..0bec8db1 100644
--- a/libs/sysplugins/smarty_internal_utility.php
+++ b/libs/sysplugins/smarty_internal_utility.php
@@ -58,7 +58,7 @@ class Smarty_Internal_Utility {
      * @param Smarty $smarty        Smarty instance
      * @return integer number of template files compiled
      */
-    public static function compileAllTemplates($extention, $force_compile, $time_limit, $max_errors, Smarty $smarty)
+    public static function compileAllTemplates($extension, $force_compile, $time_limit, $max_errors, Smarty $smarty)
     {
         // switch off time limit
         if (function_exists('set_time_limit')) {
@@ -74,7 +74,7 @@ class Smarty_Internal_Utility {
             foreach ($_compile as $_fileinfo) {
                 $_file = $_fileinfo->getFilename();
                 if (substr(basename($_fileinfo->getPathname()),0,1) == '.' || strpos($_file, '.svn') !== false) continue;
-                if (!substr_compare($_file, $extention, - strlen($extention)) == 0) continue;
+                if (!substr_compare($_file, $extension, - strlen($extension)) == 0) continue;
                 if ($_fileinfo->getPath() == substr($_dir, 0, -1)) {
                    $_template_file = $_file;
                 } else {
@@ -122,7 +122,7 @@ class Smarty_Internal_Utility {
      * @param Smarty $smarty        Smarty instance
      * @return integer number of config files compiled
      */
-    public static function compileAllConfig($extention, $force_compile, $time_limit, $max_errors, Smarty $smarty)
+    public static function compileAllConfig($extension, $force_compile, $time_limit, $max_errors, Smarty $smarty)
     {
         // switch off time limit
         if (function_exists('set_time_limit')) {
@@ -138,7 +138,7 @@ class Smarty_Internal_Utility {
             foreach ($_compile as $_fileinfo) {
                 $_file = $_fileinfo->getFilename();
                 if (substr(basename($_fileinfo->getPathname()),0,1) == '.' || strpos($_file, '.svn') !== false) continue;
-                if (!substr_compare($_file, $extention, - strlen($extention)) == 0) continue;
+                if (!substr_compare($_file, $extension, - strlen($extension)) == 0) continue;
                 if ($_fileinfo->getPath() == substr($_dir, 0, -1)) {
                     $_config_file = $_file;
                 } else {
@@ -308,7 +308,7 @@ class Smarty_Internal_Utility {
         foreach($smarty->getTemplateDir() as $template_dir) {
             $_template_dir = $template_dir;
             $template_dir = realpath($template_dir);
-            // resolve include_path or fail existance
+            // resolve include_path or fail existence
             if (!$template_dir) {
                 if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_template_dir)) {
                     // try PHP include_path
@@ -429,7 +429,7 @@ class Smarty_Internal_Utility {
         foreach($smarty->getPluginsDir() as $plugin_dir) {
             $_plugin_dir = $plugin_dir;
             $plugin_dir = realpath($plugin_dir);
-            // resolve include_path or fail existance
+            // resolve include_path or fail existence
             if (!$plugin_dir) {
                 if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_plugin_dir)) {
                     // try PHP include_path
@@ -561,7 +561,7 @@ class Smarty_Internal_Utility {
         foreach($smarty->getConfigDir() as $config_dir) {
             $_config_dir = $config_dir;
             $config_dir = realpath($config_dir);
-            // resolve include_path or fail existance
+            // resolve include_path or fail existence
             if (!$config_dir) {
                 if ($smarty->use_include_path && !preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_config_dir)) {
                     // try PHP include_path
diff --git a/libs/sysplugins/smarty_resource.php b/libs/sysplugins/smarty_resource.php
index 55f1497f..0a563dfc 100644
--- a/libs/sysplugins/smarty_resource.php
+++ b/libs/sysplugins/smarty_resource.php
@@ -584,7 +584,7 @@ abstract class Smarty_Resource {
  * @author Rodney Rehm
  *
  * @property integer $timestamp Source Timestamp
- * @property boolean $exists    Source Existance
+ * @property boolean $exists    Source Existence
  * @property boolean $template  Extended Template reference
  * @property string  $content   Source Content
  */
@@ -811,7 +811,7 @@ class Smarty_Template_Compiled {
     public $timestamp = null;
 
     /**
-     * Compiled Existance
+     * Compiled Existence
      * @var boolean
      */
     public $exists = false;
diff --git a/libs/sysplugins/smarty_security.php b/libs/sysplugins/smarty_security.php
index f8b31d96..58f33787 100644
--- a/libs/sysplugins/smarty_security.php
+++ b/libs/sysplugins/smarty_security.php
@@ -77,7 +77,7 @@ class Smarty_Security {
         'nl2br',
     );
     /**
-     * This is an array of trusted PHP modifers.
+     * This is an array of trusted PHP modifiers.
      *
      * If empty all modifiers are allowed.
      * To disable all modifier set $modifiers = null.