/libs/sysplugins/smarty_cacheresource.php

https://github.com/LamCiuLoeng/BookShare · PHP · 372 lines · 167 code · 34 blank · 171 comment · 47 complexity · f0d268e3ea869b7d86e208a5e8d77cf8 MD5 · raw file

  1. <?php
  2. /**
  3. * Smarty Internal Plugin
  4. *
  5. * @package Smarty
  6. * @subpackage Cacher
  7. */
  8. /**
  9. * Cache Handler API
  10. *
  11. * @package Smarty
  12. * @subpackage Cacher
  13. * @author Rodney Rehm
  14. */
  15. abstract class Smarty_CacheResource {
  16. /**
  17. * cache for Smarty_CacheResource instances
  18. * @var array
  19. */
  20. protected static $resources = array();
  21. /**
  22. * resource types provided by the core
  23. * @var array
  24. */
  25. protected static $sysplugins = array(
  26. 'file' => true,
  27. );
  28. /**
  29. * populate Cached Object with meta data from Resource
  30. *
  31. * @param Smarty_Template_Cached $cached cached object
  32. * @param Smarty_Internal_Template $_template template object
  33. * @return void
  34. */
  35. public abstract function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template);
  36. /**
  37. * populate Cached Object with timestamp and exists from Resource
  38. *
  39. * @param Smarty_Template_Cached $source cached object
  40. * @return void
  41. */
  42. public abstract function populateTimestamp(Smarty_Template_Cached $cached);
  43. /**
  44. * Read the cached template and process header
  45. *
  46. * @param Smarty_Internal_Template $_template template object
  47. * @param Smarty_Template_Cached $cached cached object
  48. * @return booelan true or false if the cached content does not exist
  49. */
  50. public abstract function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached=null);
  51. /**
  52. * Write the rendered template output to cache
  53. *
  54. * @param Smarty_Internal_Template $_template template object
  55. * @param string $content content to cache
  56. * @return boolean success
  57. */
  58. public abstract function writeCachedContent(Smarty_Internal_Template $_template, $content);
  59. /**
  60. * Return cached content
  61. *
  62. * @param Smarty_Internal_Template $_template template object
  63. * @param string $content content of cache
  64. */
  65. public function getCachedContent(Smarty_Internal_Template $_template)
  66. {
  67. if ($_template->cached->handler->process($_template)) {
  68. ob_start();
  69. $_template->properties['unifunc']($_template);
  70. return ob_get_clean();
  71. }
  72. return null;
  73. }
  74. /**
  75. * Empty cache
  76. *
  77. * @param Smarty $smarty Smarty object
  78. * @param integer $exp_time expiration time (number of seconds, not timestamp)
  79. * @return integer number of cache files deleted
  80. */
  81. public abstract function clearAll(Smarty $smarty, $exp_time=null);
  82. /**
  83. * Empty cache for a specific template
  84. *
  85. * @param Smarty $smarty Smarty object
  86. * @param string $resource_name template name
  87. * @param string $cache_id cache id
  88. * @param string $compile_id compile id
  89. * @param integer $exp_time expiration time (number of seconds, not timestamp)
  90. * @return integer number of cache files deleted
  91. */
  92. public abstract function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time);
  93. public function locked(Smarty $smarty, Smarty_Template_Cached $cached)
  94. {
  95. // theoretically locking_timeout should be checked against time_limit (max_execution_time)
  96. $start = microtime(true);
  97. $hadLock = null;
  98. while ($this->hasLock($smarty, $cached)) {
  99. $hadLock = true;
  100. if (microtime(true) - $start > $smarty->locking_timeout) {
  101. // abort waiting for lock release
  102. return false;
  103. }
  104. sleep(1);
  105. }
  106. return $hadLock;
  107. }
  108. public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached)
  109. {
  110. // check if lock exists
  111. return false;
  112. }
  113. public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached)
  114. {
  115. // create lock
  116. return true;
  117. }
  118. public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
  119. {
  120. // release lock
  121. return true;
  122. }
  123. /**
  124. * Load Cache Resource Handler
  125. *
  126. * @param Smarty $smarty Smarty object
  127. * @param string $type name of the cache resource
  128. * @return Smarty_CacheResource Cache Resource Handler
  129. */
  130. public static function load(Smarty $smarty, $type = null)
  131. {
  132. if (!isset($type)) {
  133. $type = $smarty->caching_type;
  134. }
  135. // try the instance cache
  136. if (isset(self::$resources[$type])) {
  137. return self::$resources[$type];
  138. }
  139. // try registered resource
  140. if (isset($smarty->registered_cache_resources[$type])) {
  141. // do not cache these instances as they may vary from instance to instance
  142. return $smarty->registered_cache_resources[$type];
  143. }
  144. // try sysplugins dir
  145. if (isset(self::$sysplugins[$type])) {
  146. $cache_resource_class = 'Smarty_Internal_CacheResource_' . ucfirst($type);
  147. return self::$resources[$type] = new $cache_resource_class();
  148. }
  149. // try plugins dir
  150. $cache_resource_class = 'Smarty_CacheResource_' . ucfirst($type);
  151. if ($smarty->loadPlugin($cache_resource_class)) {
  152. return self::$resources[$type] = new $cache_resource_class();
  153. }
  154. // give up
  155. throw new SmartyException("Unable to load cache resource '{$type}'");
  156. }
  157. /**
  158. * Invalid Loaded Cache Files
  159. *
  160. * @param Smarty $smarty Smarty object
  161. */
  162. public static function invalidLoadedCache(Smarty $smarty)
  163. {
  164. foreach ($smarty->template_objects as $tpl) {
  165. if (isset($tpl->cached)) {
  166. $tpl->cached->valid = false;
  167. $tpl->cached->processed = false;
  168. }
  169. }
  170. }
  171. }
  172. /**
  173. * Smarty Resource Data Object
  174. *
  175. * Cache Data Container for Template Files
  176. *
  177. * @package Smarty
  178. * @subpackage TemplateResources
  179. * @author Rodney Rehm
  180. */
  181. class Smarty_Template_Cached {
  182. /**
  183. * Source Filepath
  184. * @var string
  185. */
  186. public $filepath = false;
  187. /**
  188. * Source Content
  189. * @var string
  190. */
  191. public $content = null;
  192. /**
  193. * Source Timestamp
  194. * @var integer
  195. */
  196. public $timestamp = false;
  197. /**
  198. * Source Existance
  199. * @var boolean
  200. */
  201. public $exists = false;
  202. /**
  203. * Cache Is Valid
  204. * @var boolean
  205. */
  206. public $valid = false;
  207. /**
  208. * Cache was processed
  209. * @var boolean
  210. */
  211. public $processed = false;
  212. /**
  213. * CacheResource Handler
  214. * @var Smarty_CacheResource
  215. */
  216. public $handler = null;
  217. /**
  218. * Template Compile Id (Smarty_Internal_Template::$compile_id)
  219. * @var string
  220. */
  221. public $compile_id = null;
  222. /**
  223. * Template Cache Id (Smarty_Internal_Template::$cache_id)
  224. * @var string
  225. */
  226. public $cache_id = null;
  227. /**
  228. * Id for cache locking
  229. * @var string
  230. */
  231. public $lock_id = null;
  232. /**
  233. * flag that cache is locked by this instance
  234. * @var bool
  235. */
  236. public $is_locked = false;
  237. /**
  238. * Source Object
  239. * @var Smarty_Template_Source
  240. */
  241. public $source = null;
  242. /**
  243. * create Cached Object container
  244. *
  245. * @param Smarty_Internal_Template $_template template object
  246. */
  247. public function __construct(Smarty_Internal_Template $_template)
  248. {
  249. $this->compile_id = $_template->compile_id;
  250. $this->cache_id = $_template->cache_id;
  251. $this->source = $_template->source;
  252. $_template->cached = $this;
  253. $smarty = $_template->smarty;
  254. //
  255. // load resource handler
  256. //
  257. $this->handler = $handler = Smarty_CacheResource::load($smarty); // Note: prone to circular references
  258. //
  259. // check if cache is valid
  260. //
  261. if (!($_template->caching == Smarty::CACHING_LIFETIME_CURRENT || $_template->caching == Smarty::CACHING_LIFETIME_SAVED) || $_template->source->recompiled) {
  262. return;
  263. }
  264. while (true) {
  265. while (true) {
  266. $handler->populate($this, $_template);
  267. if ($this->timestamp === false || $smarty->force_compile || $smarty->force_cache) {
  268. $this->valid = false;
  269. } else {
  270. $this->valid = true;
  271. }
  272. if ($this->valid && $_template->caching == Smarty::CACHING_LIFETIME_CURRENT && $_template->cache_lifetime >= 0 && time() > ($this->timestamp + $_template->cache_lifetime)) {
  273. // lifetime expired
  274. $this->valid = false;
  275. }
  276. if ($this->valid || !$_template->smarty->cache_locking) {
  277. break;
  278. }
  279. if (!$this->handler->locked($_template->smarty, $this)) {
  280. $this->handler->acquireLock($_template->smarty, $this);
  281. break 2;
  282. }
  283. }
  284. if ($this->valid) {
  285. if (!$_template->smarty->cache_locking || $this->handler->locked($_template->smarty, $this) === null) {
  286. // load cache file for the following checks
  287. if ($smarty->debugging) {
  288. Smarty_Internal_Debug::start_cache($_template);
  289. }
  290. if($handler->process($_template, $this) === false) {
  291. $this->valid = false;
  292. } else {
  293. $this->processed = true;
  294. }
  295. if ($smarty->debugging) {
  296. Smarty_Internal_Debug::end_cache($_template);
  297. }
  298. } else {
  299. continue;
  300. }
  301. } else {
  302. return;
  303. }
  304. if ($this->valid && $_template->caching === Smarty::CACHING_LIFETIME_SAVED && $_template->properties['cache_lifetime'] >= 0 && (time() > ($_template->cached->timestamp + $_template->properties['cache_lifetime']))) {
  305. $this->valid = false;
  306. }
  307. if (!$this->valid && $_template->smarty->cache_locking) {
  308. $this->handler->acquireLock($_template->smarty, $this);
  309. return;
  310. } else {
  311. return;
  312. }
  313. }
  314. }
  315. /**
  316. * Write this cache object to handler
  317. *
  318. * @param Smarty_Internal_Template $_template template object
  319. * @param string $content content to cache
  320. * @return boolean success
  321. */
  322. public function write(Smarty_Internal_Template $_template, $content)
  323. {
  324. if (!$_template->source->recompiled) {
  325. if ($this->handler->writeCachedContent($_template, $content)) {
  326. $this->timestamp = time();
  327. $this->exists = true;
  328. $this->valid = true;
  329. if ($_template->smarty->cache_locking) {
  330. $this->handler->releaseLock($_template->smarty, $this);
  331. }
  332. return true;
  333. }
  334. }
  335. return false;
  336. }
  337. }
  338. ?>