1<?php 2/** 3 * Created by PhpStorm. 4 * User: Uwe Tews 5 * Date: 04.12.2014 6 * Time: 06:08 7 */ 8 9/** 10 * Smarty Resource Data Object 11 * Cache Data Container for Template Files 12 * 13 * @package Smarty 14 * @subpackage TemplateResources 15 * @author Rodney Rehm 16 */ 17class Smarty_Template_Cached extends Smarty_Template_Resource_Base 18{ 19 /** 20 * Cache Is Valid 21 * 22 * @var boolean 23 */ 24 public $valid = null; 25 26 /** 27 * CacheResource Handler 28 * 29 * @var Smarty_CacheResource 30 */ 31 public $handler = null; 32 33 /** 34 * Template Cache Id (Smarty_Internal_Template::$cache_id) 35 * 36 * @var string 37 */ 38 public $cache_id = null; 39 40 /** 41 * saved cache lifetime in seconds 42 * 43 * @var integer 44 */ 45 public $cache_lifetime = 0; 46 47 /** 48 * Id for cache locking 49 * 50 * @var string 51 */ 52 public $lock_id = null; 53 54 /** 55 * flag that cache is locked by this instance 56 * 57 * @var bool 58 */ 59 public $is_locked = false; 60 61 /** 62 * Source Object 63 * 64 * @var Smarty_Template_Source 65 */ 66 public $source = null; 67 68 /** 69 * Nocache hash codes of processed compiled templates 70 * 71 * @var array 72 */ 73 public $hashes = array(); 74 75 /** 76 * Flag if this is a cache resource 77 * 78 * @var bool 79 */ 80 public $isCache = true; 81 82 /** 83 * create Cached Object container 84 * 85 * @param Smarty_Internal_Template $_template template object 86 * 87 * @throws \SmartyException 88 */ 89 public function __construct(Smarty_Internal_Template $_template) 90 { 91 $this->compile_id = $_template->compile_id; 92 $this->cache_id = $_template->cache_id; 93 $this->source = $_template->source; 94 if (!class_exists('Smarty_CacheResource', false)) { 95 include SMARTY_SYSPLUGINS_DIR . 'smarty_cacheresource.php'; 96 } 97 $this->handler = Smarty_CacheResource::load($_template->smarty); 98 } 99 100 /** 101 * @param Smarty_Internal_Template $_template 102 * 103 * @return Smarty_Template_Cached 104 */ 105 public static function load(Smarty_Internal_Template $_template) 106 { 107 $_template->cached = new Smarty_Template_Cached($_template); 108 $_template->cached->handler->populate($_template->cached, $_template); 109 // caching enabled ? 110 if (!$_template->caching || $_template->source->handler->recompiled 111 ) { 112 $_template->cached->valid = false; 113 } 114 return $_template->cached; 115 } 116 117 /** 118 * Render cache template 119 * 120 * @param \Smarty_Internal_Template $_template 121 * @param bool $no_output_filter 122 * 123 * @throws \Exception 124 */ 125 public function render(Smarty_Internal_Template $_template, $no_output_filter = true) 126 { 127 if ($this->isCached($_template)) { 128 if ($_template->smarty->debugging) { 129 if (!isset($_template->smarty->_debug)) { 130 $_template->smarty->_debug = new Smarty_Internal_Debug(); 131 } 132 $_template->smarty->_debug->start_cache($_template); 133 } 134 if (!$this->processed) { 135 $this->process($_template); 136 } 137 $this->getRenderedTemplateCode($_template); 138 if ($_template->smarty->debugging) { 139 $_template->smarty->_debug->end_cache($_template); 140 } 141 return; 142 } else { 143 $_template->smarty->ext->_updateCache->updateCache($this, $_template, $no_output_filter); 144 } 145 } 146 147 /** 148 * Check if cache is valid, lock cache if required 149 * 150 * @param \Smarty_Internal_Template $_template 151 * 152 * @return bool flag true if cache is valid 153 */ 154 public function isCached(Smarty_Internal_Template $_template) 155 { 156 if ($this->valid !== null) { 157 return $this->valid; 158 } 159 while (true) { 160 while (true) { 161 if ($this->exists === false || $_template->smarty->force_compile || $_template->smarty->force_cache) { 162 $this->valid = false; 163 } else { 164 $this->valid = true; 165 } 166 if ($this->valid && $_template->caching === Smarty::CACHING_LIFETIME_CURRENT 167 && $_template->cache_lifetime >= 0 && time() > ($this->timestamp + $_template->cache_lifetime) 168 ) { 169 // lifetime expired 170 $this->valid = false; 171 } 172 if ($this->valid && $_template->compile_check === Smarty::COMPILECHECK_ON 173 && $_template->source->getTimeStamp() > $this->timestamp 174 ) { 175 $this->valid = false; 176 } 177 if ($this->valid || !$_template->smarty->cache_locking) { 178 break; 179 } 180 if (!$this->handler->locked($_template->smarty, $this)) { 181 $this->handler->acquireLock($_template->smarty, $this); 182 break 2; 183 } 184 $this->handler->populate($this, $_template); 185 } 186 if ($this->valid) { 187 if (!$_template->smarty->cache_locking || $this->handler->locked($_template->smarty, $this) === null) { 188 // load cache file for the following checks 189 if ($_template->smarty->debugging) { 190 $_template->smarty->_debug->start_cache($_template); 191 } 192 if ($this->handler->process($_template, $this) === false) { 193 $this->valid = false; 194 } else { 195 $this->processed = true; 196 } 197 if ($_template->smarty->debugging) { 198 $_template->smarty->_debug->end_cache($_template); 199 } 200 } else { 201 $this->is_locked = true; 202 continue; 203 } 204 } else { 205 return $this->valid; 206 } 207 if ($this->valid && $_template->caching === Smarty::CACHING_LIFETIME_SAVED 208 && $_template->cached->cache_lifetime >= 0 209 && (time() > ($_template->cached->timestamp + $_template->cached->cache_lifetime)) 210 ) { 211 $this->valid = false; 212 } 213 if ($_template->smarty->cache_locking) { 214 if (!$this->valid) { 215 $this->handler->acquireLock($_template->smarty, $this); 216 } elseif ($this->is_locked) { 217 $this->handler->releaseLock($_template->smarty, $this); 218 } 219 } 220 return $this->valid; 221 } 222 return $this->valid; 223 } 224 225 /** 226 * Process cached template 227 * 228 * @param Smarty_Internal_Template $_template template object 229 * @param bool $update flag if called because cache update 230 */ 231 public function process(Smarty_Internal_Template $_template, $update = false) 232 { 233 if ($this->handler->process($_template, $this, $update) === false) { 234 $this->valid = false; 235 } 236 if ($this->valid) { 237 $this->processed = true; 238 } else { 239 $this->processed = false; 240 } 241 } 242 243 /** 244 * Read cache content from handler 245 * 246 * @param Smarty_Internal_Template $_template template object 247 * 248 * @return string|false content 249 */ 250 public function read(Smarty_Internal_Template $_template) 251 { 252 if (!$_template->source->handler->recompiled) { 253 return $this->handler->readCachedContent($_template); 254 } 255 return false; 256 } 257} 258