diff options
Diffstat (limited to 'include/smarty/libs/sysplugins/smarty_cacheresource.php')
-rw-r--r-- | include/smarty/libs/sysplugins/smarty_cacheresource.php | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/include/smarty/libs/sysplugins/smarty_cacheresource.php b/include/smarty/libs/sysplugins/smarty_cacheresource.php new file mode 100644 index 000000000..ca18add5e --- /dev/null +++ b/include/smarty/libs/sysplugins/smarty_cacheresource.php @@ -0,0 +1,381 @@ +<?php +/** +* Smarty Internal Plugin +* +* @package Smarty +* @subpackage Cacher +*/ + +/** +* Cache Handler API +* +* @package Smarty +* @subpackage Cacher +* @author Rodney Rehm +*/ +abstract class Smarty_CacheResource { + /** + * cache for Smarty_CacheResource instances + * @var array + */ + public static $resources = array(); + + /** + * resource types provided by the core + * @var array + */ + protected static $sysplugins = array( + 'file' => true, + ); + + /** + * 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 abstract function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template); + + /** + * populate Cached Object with timestamp and exists from Resource + * + * @param Smarty_Template_Cached $source cached object + * @return void + */ + public abstract function populateTimestamp(Smarty_Template_Cached $cached); + + /** + * Read the cached template and process 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 abstract function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached=null); + + /** + * Write the rendered template output to cache + * + * @param Smarty_Internal_Template $_template template object + * @param string $content content to cache + * @return boolean success + */ + public abstract function writeCachedContent(Smarty_Internal_Template $_template, $content); + + /** + * Return cached content + * + * @param Smarty_Internal_Template $_template template object + * @param string $content content of cache + */ + public function getCachedContent(Smarty_Internal_Template $_template) + { + if ($_template->cached->handler->process($_template)) { + ob_start(); + $_template->properties['unifunc']($_template); + return ob_get_clean(); + } + return null; + } + + /** + * Empty cache + * + * @param Smarty $smarty Smarty object + * @param integer $exp_time expiration time (number of seconds, not timestamp) + * @return integer number of cache files deleted + */ + public abstract function clearAll(Smarty $smarty, $exp_time=null); + + /** + * Empty cache for a specific template + * + * @param Smarty $smarty Smarty 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 abstract function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time); + + + public function locked(Smarty $smarty, Smarty_Template_Cached $cached) + { + // theoretically locking_timeout should be checked against time_limit (max_execution_time) + $start = microtime(true); + $hadLock = null; + while ($this->hasLock($smarty, $cached)) { + $hadLock = true; + if (microtime(true) - $start > $smarty->locking_timeout) { + // abort waiting for lock release + return false; + } + sleep(1); + } + return $hadLock; + } + + public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached) + { + // check if lock exists + return false; + } + + public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached) + { + // create lock + return true; + } + + public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached) + { + // release lock + return true; + } + + + /** + * Load Cache Resource Handler + * + * @param Smarty $smarty Smarty object + * @param string $type name of the cache resource + * @return Smarty_CacheResource Cache Resource Handler + */ + public static function load(Smarty $smarty, $type = null) + { + if (!isset($type)) { + $type = $smarty->caching_type; + } + + // try smarty's cache + if (isset($smarty->_cacheresource_handlers[$type])) { + return $smarty->_cacheresource_handlers[$type]; + } + + // try registered resource + if (isset($smarty->registered_cache_resources[$type])) { + // do not cache these instances as they may vary from instance to instance + return $smarty->_cacheresource_handlers[$type] = $smarty->registered_cache_resources[$type]; + } + // try sysplugins dir + if (isset(self::$sysplugins[$type])) { + if (!isset(self::$resources[$type])) { + $cache_resource_class = 'Smarty_Internal_CacheResource_' . ucfirst($type); + self::$resources[$type] = new $cache_resource_class(); + } + return $smarty->_cacheresource_handlers[$type] = self::$resources[$type]; + } + // try plugins dir + $cache_resource_class = 'Smarty_CacheResource_' . ucfirst($type); + if ($smarty->loadPlugin($cache_resource_class)) { + if (!isset(self::$resources[$type])) { + self::$resources[$type] = new $cache_resource_class(); + } + return $smarty->_cacheresource_handlers[$type] = self::$resources[$type]; + } + // give up + throw new SmartyException("Unable to load cache resource '{$type}'"); + } + + /** + * Invalid Loaded Cache Files + * + * @param Smarty $smarty Smarty object + */ + public static function invalidLoadedCache(Smarty $smarty) + { + foreach ($smarty->template_objects as $tpl) { + if (isset($tpl->cached)) { + $tpl->cached->valid = false; + $tpl->cached->processed = false; + } + } + } +} + +/** +* Smarty Resource Data Object +* +* Cache Data Container for Template Files +* +* @package Smarty +* @subpackage TemplateResources +* @author Rodney Rehm +*/ +class Smarty_Template_Cached { + /** + * Source Filepath + * @var string + */ + public $filepath = false; + + /** + * Source Content + * @var string + */ + public $content = null; + + /** + * Source Timestamp + * @var integer + */ + public $timestamp = false; + + /** + * Source Existance + * @var boolean + */ + public $exists = false; + + /** + * Cache Is Valid + * @var boolean + */ + public $valid = false; + + /** + * Cache was processed + * @var boolean + */ + public $processed = false; + + /** + * CacheResource Handler + * @var Smarty_CacheResource + */ + public $handler = null; + + /** + * Template Compile Id (Smarty_Internal_Template::$compile_id) + * @var string + */ + public $compile_id = null; + + /** + * Template Cache Id (Smarty_Internal_Template::$cache_id) + * @var string + */ + public $cache_id = null; + + /** + * Id for cache locking + * @var string + */ + public $lock_id = null; + + /** + * flag that cache is locked by this instance + * @var bool + */ + public $is_locked = false; + + /** + * Source Object + * @var Smarty_Template_Source + */ + public $source = null; + + /** + * create Cached Object container + * + * @param Smarty_Internal_Template $_template template object + */ + public function __construct(Smarty_Internal_Template $_template) + { + $this->compile_id = $_template->compile_id; + $this->cache_id = $_template->cache_id; + $this->source = $_template->source; + $_template->cached = $this; + $smarty = $_template->smarty; + + // + // load resource handler + // + $this->handler = $handler = Smarty_CacheResource::load($smarty); // Note: prone to circular references + + // + // check if cache is valid + // + if (!($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED) || $_template->source->recompiled) { + $handler->populate($this, $_template); + return; + } + while (true) { + while (true) { + $handler->populate($this, $_template); + if ($this->timestamp === false || $smarty->force_compile || $smarty->force_cache) { + $this->valid = false; + } else { + $this->valid = true; + } + if ($this->valid && $_template->caching == Smarty::CACHING_LIFETIME_CURRENT && $_template->cache_lifetime >= 0 && time() > ($this->timestamp + $_template->cache_lifetime)) { + // lifetime expired + $this->valid = false; + } + if ($this->valid || !$_template->smarty->cache_locking) { + break; + } + if (!$this->handler->locked($_template->smarty, $this)) { + $this->handler->acquireLock($_template->smarty, $this); + break 2; + } + } + if ($this->valid) { + if (!$_template->smarty->cache_locking || $this->handler->locked($_template->smarty, $this) === null) { + // load cache file for the following checks + if ($smarty->debugging) { + Smarty_Internal_Debug::start_cache($_template); + } + if($handler->process($_template, $this) === false) { + $this->valid = false; + } else { + $this->processed = true; + } + if ($smarty->debugging) { + Smarty_Internal_Debug::end_cache($_template); + } + } else { + continue; + } + } else { + return; + } + if ($this->valid && $_template->caching === Smarty::CACHING_LIFETIME_SAVED && $_template->properties['cache_lifetime'] >= 0 && (time() > ($_template->cached->timestamp + $_template->properties['cache_lifetime']))) { + $this->valid = false; + } + if (!$this->valid && $_template->smarty->cache_locking) { + $this->handler->acquireLock($_template->smarty, $this); + return; + } else { + return; + } + } + } + + /** + * Write this cache object to handler + * + * @param Smarty_Internal_Template $_template template object + * @param string $content content to cache + * @return boolean success + */ + public function write(Smarty_Internal_Template $_template, $content) + { + if (!$_template->source->recompiled) { + if ($this->handler->writeCachedContent($_template, $content)) { + $this->timestamp = time(); + $this->exists = true; + $this->valid = true; + if ($_template->smarty->cache_locking) { + $this->handler->releaseLock($_template->smarty, $this); + } + return true; + } + } + return false; + } + +} +?>
\ No newline at end of file |