source: trunk/include/smarty/libs/sysplugins/smarty_cacheresource.php @ 23384

Last change on this file since 23384 was 23384, checked in by rvelices, 11 years ago

smarty 3 - first pass for tests

File size: 11.1 KB
Line 
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*/
16abstract 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*/
207class 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?>
Note: See TracBrowser for help on using the repository browser.