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