diff --git a/change_log.txt b/change_log.txt index fa575496..a80c0e58 100644 --- a/change_log.txt +++ b/change_log.txt @@ -1,3 +1,6 @@ +11/27/2009 +- added cache resource MYSQL plugin + 11/26/2009 - bugfix on nested doublequoted strings - correct line number on unknown tag error message diff --git a/libs/Smarty.class.php b/libs/Smarty.class.php index ecabcae0..3a755235 100644 --- a/libs/Smarty.class.php +++ b/libs/Smarty.class.php @@ -62,7 +62,7 @@ if (!defined('SMARTY_RESOURCE_CHAR_SET')) { if (!defined('SMARTY_RESOURCE_DATE_FORMAT')) { define('SMARTY_RESOURCE_DATE_FORMAT', '%b %e, %Y'); } - + /** * define variable scopes */ @@ -167,7 +167,7 @@ class Smarty extends Smarty_Internal_TemplateBase { // config var settings public $config_overwrite = true; //Controls whether variables with the same name overwrite each other. public $config_booleanize = true; //Controls whether config values of on/true/yes and off/false/no get converted to boolean - public $config_read_hidden = true; //Controls whether hidden config sections/vars are read from the file. + public $config_read_hidden = true; //Controls whether hidden config sections/vars are read from the file. // config vars public $config_vars = array(); // assigned tpl vars @@ -181,9 +181,9 @@ class Smarty extends Smarty_Internal_TemplateBase { // resource type used if none given public $default_resource_type = 'file'; // caching type - public $default_caching_type = 'file'; + public $caching_type = 'file'; // internal cache resource types - public $cache_resorce_types = array('file'); + public $cache_resource_types = array('file'); // config type public $default_config_type = 'file'; // class used for cacher @@ -331,7 +331,7 @@ class Smarty extends Smarty_Internal_TemplateBase { * @param object $parent next higher level of Smarty variables */ public function display($template, $cache_id = null, $compile_id = null, $parent = null) - { + { // display template echo $this->fetch ($template, $cache_id, $compile_id, $parent); // debug output @@ -493,6 +493,34 @@ class Smarty extends Smarty_Internal_TemplateBase { return set_exception_handler($handler); } + /** + * Loads cache resource. + * + * @return object of cache resource + */ + public function loadCacheResource($type = null) + { + if (!isset($type)) { + $type = $this->caching_type; + } + // already loaded? + if (isset($this->cache_resource_objects[$type])) { + return $this->cache_resource_objects[$type]; + } + if (in_array($type, $this->cache_resource_types)) { + $cache_resource_class = 'Smarty_Internal_CacheResource_' . ucfirst($type); + return $this->cache_resource_objects[$type] = new $cache_resource_class($this); + } else { + // try plugins dir + $cache_resource_class = 'Smarty_CacheResource_' . ucfirst($type); + if ($this->loadPlugin($cache_resource_class)) { + return $this->cache_resource_objects[$type] = new $cache_resource_class($this); + } else { + throw new Exception("Unable to load cache resource '{$type}'"); + } + } + } + /** * trigger Smarty error * diff --git a/libs/plugins/cacheresource.mysql.php b/libs/plugins/cacheresource.mysql.php new file mode 100644 index 00000000..c3133ed3 --- /dev/null +++ b/libs/plugins/cacheresource.mysql.php @@ -0,0 +1,191 @@ +smarty = $smarty; + if (!$this->link = mysql_pconnect($this->db_host, $this->db_user, $this->db_pass)) { + throw new Exception("Cache resource unable to connect to MYSQL"); + } + mysql_select_db($this->db_name, $this->link); + } + /** + * Returns the filepath of the cached template output + * + * @param object $template current template + * @return string the cache filepath + */ + public function getCachedFilepath($template) + { + return $this->buildCachedFilepath ($template->resource_name, $template->cache_id, $template->compile_id); + } + + /** + * Returns the timpestamp of the cached template output + * + * @param object $template current template + * @return integer |booelan the template timestamp or false if the file does not exist + */ + public function getCachedTimestamp($template) + { + $Id = $template->getCachedFilepath(); + // read cache from database + $results = mysql_query("select UNIX_TIMESTAMP(Timestamp) from SMARTY_CACHE where Id='$Id'", $this->link); + if (!$results) { + $this->mysqlError(); + } + $row = mysql_fetch_row($results); + return (int)$row[0]; + } + + /** + * Returns the cached template output + * + * @param object $template current template + * @return string |booelan the template content or false if the file does not exist + */ + public function getCachedContents($template) + { + $Id = $template->getCachedFilepath(); + // read cache from database + $results = mysql_query("select CacheContents from SMARTY_CACHE where Id='$Id'", $this->link); + if (!$results) { + $this->mysqlError(); + } + $row = mysql_fetch_row($results); + + $cache_content = $row[0]; + + $_smarty_tpl = $template; + ob_start(); + eval("?>" . $cache_content); + return ob_get_clean(); + } + + /** + * Writes the rendered template output to cache file + * + * @param object $template current template + * @return boolean status + */ + public function writeCachedContent($template, $content) + { + if (!$template->isEvaluated()) { + $_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; + // save cache to database + $Id = $template->getCachedFilepath(); + $results = mysql_query("replace into SMARTY_CACHE set Id = $Id, CacheContents = '" . addslashes($content) . "', + CacheId = '$_cache_id', + CompileId = '$_compile_id', + ResourceName = '$template->resource_name'", $this->link); + if (!$results) { + $this->mysqlError(); + } + return $results; + } else { + return false; + } + } + + /** + * Empty cache folder + * + * @param integer $exp_time expiration time + * @return integer number of cache files deleted + */ + public function clearAll($exp_time = null) + { + if ($exp_time === null) { + $results = mysql_query("truncate table SMARTY_CACHE", $this->link); + } else { + $results = mysql_query("delete ignore from SMARTY_CACHE where UNIX_TIMESTAMP(Timestamp) <= '$exp_time'", $this->link); + } + if (!$results) { + $this->mysqlError(); + } + } + /** + * Empty cache for a specific template + * + * @param string $resource_name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @param integer $exp_time expiration time + * @return integer number of cache files deleted + */ + public function clear($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; + + $where = ''; + $and = ''; + if (isset($resource_name)) { + $where = "ResourceName = '$resource_name' "; + $and = 'and '; + } + if (isset($_cache_id)) { + $length = strlen($_cache_id); + $where .= $and . "SUBSTRING(CacheId,1,$length) = '$_cache_id' "; + $and = 'and '; + } + if (isset($_compile_id)) { + $where .= $and . "CompileId = '$_compile_id' "; + $and = 'and '; + } + if (isset($exp_time)) { + $where .= $and . "UNIX_TIMESTAMP(Timestamp) <= '$exp_time' "; + } + $results = mysql_query("delete ignore from SMARTY_CACHE where $where", $this->link); + if (!$results) { + $this->mysqlError(); + } + return mysql_affected_rows(); + } + + /** + * Get system filepath to cached file + * + * @param string $resource_name template name + * @param string $cache_id cache id + * @param string $compile_id compile id + * @return string filepath of cache file + */ + private function buildCachedFilepath ($resource_name, $cache_id, $compile_id) + { + $_cache_id = isset($cache_id) ? preg_replace('![^\w\|]+!', '_', $cache_id) : null; + $_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null; + return abs(crc32($resource_name . $_cache_id . $_compile_id)); + } + + /** + * MYSQL Error + */ + private function mysqlError () + { + $error = mysql_error($this->link); + throw new Exception("Cache resource MYSQL error '{$error}'"); + } +} + +?> diff --git a/libs/sysplugins/smarty_internal_template.php b/libs/sysplugins/smarty_internal_template.php index 4c5073db..a649c78b 100644 --- a/libs/sysplugins/smarty_internal_template.php +++ b/libs/sysplugins/smarty_internal_template.php @@ -24,7 +24,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase { public $cache_lifetime = null; public $cacher_class = null; public $caching_type = null; - public $force_compile = null; + public $force_compile = null; public $forceNocache = false; // Template resource public $template_resource = null; @@ -87,9 +87,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase { $this->cache_lifetime = $_cache_lifetime === null ?$this->smarty->cache_lifetime : $_cache_lifetime; $this->force_cache = $this->smarty->force_cache; $this->cacher_class = $this->smarty->cacher_class; - $this->caching_type = $this->smarty->default_caching_type; $this->security = $this->smarty->security; - $this->cache_resource_class = 'Smarty_Internal_CacheResource_' . ucfirst($this->caching_type); $this->parent = $_parent; $this->properties['file_dependency'] = array(); // dummy local smarty variable @@ -102,7 +100,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase { } // load cache resource if (!$this->isEvaluated() && $this->caching) { - $this->cache_resource_object = new $this->cache_resource_class($this->smarty); + $this->cache_resource_object = $this->smarty->loadCacheResource(); } } @@ -207,8 +205,8 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase { { $this->isExisting(true); if ($this->mustCompile === null) { - $this->mustCompile = ($this->usesCompiler() && ($this->force_compile || $this->isEvaluated() || $this->getCompiledTimestamp () === false || -// ($this->smarty->compile_check && $this->getCompiledTimestamp () !== $this->getTemplateTimestamp ()))); + $this->mustCompile = ($this->usesCompiler() && ($this->force_compile || $this->isEvaluated() || $this->getCompiledTimestamp () === false || + // ($this->smarty->compile_check && $this->getCompiledTimestamp () !== $this->getTemplateTimestamp ()))); ($this->smarty->compile_check && $this->getCompiledTimestamp () < $this->getTemplateTimestamp ()))); } return $this->mustCompile; @@ -291,14 +289,14 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase { // write compiled template Smarty_Internal_Write_File::writeFile($this->getCompiledFilepath(), $this->compiled_template, $this->smarty); // make template and compiled file timestamp match -/** - $this->compiled_timestamp = null; - touch($this->getCompiledFilepath(), $this->getTemplateTimestamp()); - // daylight saving time problem on windows - if ($this->template_timestamp != $this->getCompiledTimestamp()) { - touch($this->getCompiledFilepath(), 2 * $this->template_timestamp - $this->compiled_timestamp); - } -**/ + /** + * $this->compiled_timestamp = null; + * touch($this->getCompiledFilepath(), $this->getTemplateTimestamp()); + * // daylight saving time problem on windows + * if ($this->template_timestamp != $this->getCompiledTimestamp()) { + * touch($this->getCompiledFilepath(), 2 * $this->template_timestamp - $this->compiled_timestamp); + * } + */ } } else { // error compiling template @@ -445,7 +443,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase { $resource_handler = $this->loadTemplateResourceHandler($resource_type); $mtime = $resource_handler->getTemplateTimestampTypeName($resource_type, $resource_name); } -// If ($mtime != $_file_to_check[1]) { + // If ($mtime != $_file_to_check[1]) { If ($mtime > $_file_to_check[1]) { $this->properties['file_dependency'] = array(); $this->mustCompile = true; @@ -577,7 +575,7 @@ class Smarty_Internal_Template extends Smarty_Internal_TemplateBase { return $_return; } elseif ($_return === true) { return $file; - } + } } } // throw new Exception("Unable to load template \"{$file}\""); diff --git a/libs/sysplugins/smarty_method_clear_all_cache.php b/libs/sysplugins/smarty_method_clear_all_cache.php index ca7dd014..2d263156 100644 --- a/libs/sysplugins/smarty_method_clear_all_cache.php +++ b/libs/sysplugins/smarty_method_clear_all_cache.php @@ -18,18 +18,12 @@ * @param string $type resource type * @return integer number of cache files deleted */ -function Smarty_Method_Clear_All_Cache($smarty, $exp_time = null, $type = 'file') +function Smarty_Method_Clear_All_Cache($smarty, $exp_time = null, $type = null) { // load cache resource - if (!isset($smarty->cache_resource_objects[$type])) { - $_cache_resource_class = 'Smarty_Internal_CacheResource_' . $type; - if (!$smarty->loadPlugin($_cache_resource_class)) { - throw new Exception("Undefined cache resource type {$type}"); - } - $smarty->cache_resource_objects[$type] = new $_cache_resource_class($smarty); - } + $cacheResource = $smarty->loadCacheResource($type); - return $smarty->cache_resource_objects[$type]->clearAll($exp_time); + return $cacheResource->clearAll($exp_time); } ?> diff --git a/libs/sysplugins/smarty_method_clear_cache.php b/libs/sysplugins/smarty_method_clear_cache.php index c84edd01..59b79d77 100644 --- a/libs/sysplugins/smarty_method_clear_cache.php +++ b/libs/sysplugins/smarty_method_clear_cache.php @@ -21,16 +21,12 @@ * @param string $type resource type * @return integer number of cache files deleted */ -function Smarty_Method_Clear_Cache($smarty, $template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = 'file') +function Smarty_Method_Clear_Cache($smarty, $template_name, $cache_id = null, $compile_id = null, $exp_time = null, $type = null) { - // load cache resource - $_cache_resource_class = 'Smarty_Internal_CacheResource_' . $type; - if (!$smarty->loadPlugin($_cache_resource_class)) { - throw new Exception("Undefined cache resource type {$type}"); - } - $cache_object = new $_cache_resource_class($smarty); + // load cache resource + $cacheResource = $smarty->loadCacheResource($type); - return $cache_object->clear($template_name, $cache_id, $compile_id, $exp_time); + return $cacheResource->clear($template_name, $cache_id, $compile_id, $exp_time); } ?>