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