|
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_Custom extends Smarty_CacheResource { |
|
17 /** |
|
18 * fetch cached content and its modification time from data source |
|
19 * |
|
20 * @param string $id unique cache content identifier |
|
21 * @param string $name template name |
|
22 * @param string $cache_id cache id |
|
23 * @param string $compile_id compile id |
|
24 * @param string $content cached content |
|
25 * @param integer $mtime cache modification timestamp (epoch) |
|
26 * |
|
27 * @return void |
|
28 */ |
|
29 abstract protected function fetch($id, $name, $cache_id, $compile_id, &$content, &$mtime); |
|
30 |
|
31 /** |
|
32 * Fetch cached content's modification timestamp from data source |
|
33 * {@internal implementing this method is optional. |
|
34 * Only implement it if modification times can be accessed faster than loading the complete cached content.}} |
|
35 * |
|
36 * @param string $id unique cache content identifier |
|
37 * @param string $name template name |
|
38 * @param string $cache_id cache id |
|
39 * @param string $compile_id compile id |
|
40 * |
|
41 * @return integer|boolean timestamp (epoch) the template was modified, or false if not found |
|
42 */ |
|
43 protected function fetchTimestamp($id, $name, $cache_id, $compile_id) { |
|
44 return null; |
|
45 } |
|
46 |
|
47 /** |
|
48 * Save content to cache |
|
49 * |
|
50 * @param string $id unique cache content identifier |
|
51 * @param string $name template name |
|
52 * @param string $cache_id cache id |
|
53 * @param string $compile_id compile id |
|
54 * @param integer|null $exp_time seconds till expiration or null |
|
55 * @param string $content content to cache |
|
56 * |
|
57 * @return boolean success |
|
58 */ |
|
59 abstract protected function save($id, $name, $cache_id, $compile_id, $exp_time, $content); |
|
60 |
|
61 /** |
|
62 * Delete content from cache |
|
63 * |
|
64 * @param string $name template name |
|
65 * @param string $cache_id cache id |
|
66 * @param string $compile_id compile id |
|
67 * @param integer|null $exp_time seconds till expiration time in seconds or null |
|
68 * |
|
69 * @return integer number of deleted caches |
|
70 */ |
|
71 abstract protected function delete($name, $cache_id, $compile_id, $exp_time); |
|
72 |
|
73 /** |
|
74 * populate Cached Object with meta data from Resource |
|
75 * |
|
76 * @param Smarty_Template_Cached $cached cached object |
|
77 * @param Smarty_Internal_Template $_template template object |
|
78 * |
|
79 * @return void |
|
80 */ |
|
81 public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template) { |
|
82 $_cache_id = isset($cached->cache_id) ? preg_replace('![^\w\|]+!', '_', $cached->cache_id) : null; |
|
83 $_compile_id = isset($cached->compile_id) ? preg_replace('![^\w\|]+!', '_', $cached->compile_id) : null; |
|
84 $path = $cached->source->filepath . $_cache_id . $_compile_id; |
|
85 $cached->filepath = sha1($path); |
|
86 if ($_template->smarty->cache_locking) { |
|
87 $cached->lock_id = sha1('lock.' . $path); |
|
88 } |
|
89 $this->populateTimestamp($cached); |
|
90 } |
|
91 |
|
92 /** |
|
93 * populate Cached Object with timestamp and exists from Resource |
|
94 * |
|
95 * @param Smarty_Template_Cached $cached |
|
96 * |
|
97 * @return void |
|
98 */ |
|
99 public function populateTimestamp(Smarty_Template_Cached $cached) { |
|
100 $mtime = $this->fetchTimestamp($cached->filepath, $cached->source->name, $cached->cache_id, $cached->compile_id); |
|
101 if ($mtime !== null) { |
|
102 $cached->timestamp = $mtime; |
|
103 $cached->exists = !!$cached->timestamp; |
|
104 |
|
105 return; |
|
106 } |
|
107 $timestamp = null; |
|
108 $this->fetch($cached->filepath, $cached->source->name, $cached->cache_id, $cached->compile_id, $cached->content, $timestamp); |
|
109 $cached->timestamp = isset($timestamp) ? $timestamp : false; |
|
110 $cached->exists = !!$cached->timestamp; |
|
111 } |
|
112 |
|
113 /** |
|
114 * Read the cached template and process the header |
|
115 * |
|
116 * @param Smarty_Internal_Template $_template template object |
|
117 * @param Smarty_Template_Cached $cached cached object |
|
118 * |
|
119 * @return boolean true or false if the cached content does not exist |
|
120 */ |
|
121 public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached = null) { |
|
122 if (!$cached) { |
|
123 $cached = $_template->cached; |
|
124 } |
|
125 $content = $cached->content ? $cached->content : null; |
|
126 $timestamp = $cached->timestamp ? $cached->timestamp : null; |
|
127 if ($content === null || !$timestamp) { |
|
128 $this->fetch( |
|
129 $_template->cached->filepath, |
|
130 $_template->source->name, |
|
131 $_template->cache_id, |
|
132 $_template->compile_id, |
|
133 $content, |
|
134 $timestamp |
|
135 ); |
|
136 } |
|
137 if (isset($content)) { |
|
138 /** @var Smarty_Internal_Template $_smarty_tpl |
|
139 * used in evaluated code |
|
140 */ |
|
141 $_smarty_tpl = $_template; |
|
142 eval("?>" . $content); |
|
143 |
|
144 return true; |
|
145 } |
|
146 |
|
147 return false; |
|
148 } |
|
149 |
|
150 /** |
|
151 * Write the rendered template output to cache |
|
152 * |
|
153 * @param Smarty_Internal_Template $_template template object |
|
154 * @param string $content content to cache |
|
155 * |
|
156 * @return boolean success |
|
157 */ |
|
158 public function writeCachedContent(Smarty_Internal_Template $_template, $content) { |
|
159 return $this->save( |
|
160 $_template->cached->filepath, |
|
161 $_template->source->name, |
|
162 $_template->cache_id, |
|
163 $_template->compile_id, |
|
164 $_template->properties['cache_lifetime'], |
|
165 $content |
|
166 ); |
|
167 } |
|
168 |
|
169 /** |
|
170 * Read cached template from cache |
|
171 * |
|
172 * @param Smarty_Internal_Template $_template template object |
|
173 * |
|
174 * @return string content |
|
175 */ |
|
176 public function readCachedContent(Smarty_Internal_Template $_template) { |
|
177 $content = $_template->cached->content ? $_template->cached->content : null; |
|
178 $timestamp = null; |
|
179 if ($content === null) { |
|
180 $timestamp = null; |
|
181 $this->fetch( |
|
182 $_template->cached->filepath, |
|
183 $_template->source->name, |
|
184 $_template->cache_id, |
|
185 $_template->compile_id, |
|
186 $content, |
|
187 $timestamp |
|
188 ); |
|
189 } |
|
190 if (isset($content)) { |
|
191 return $content; |
|
192 } |
|
193 return false; |
|
194 } |
|
195 |
|
196 /** |
|
197 * Empty cache |
|
198 * |
|
199 * @param Smarty $smarty Smarty object |
|
200 * @param integer $exp_time expiration time (number of seconds, not timestamp) |
|
201 * |
|
202 * @return integer number of cache files deleted |
|
203 */ |
|
204 public function clearAll(Smarty $smarty, $exp_time = null) { |
|
205 $this->cache = array(); |
|
206 |
|
207 return $this->delete(null, null, null, $exp_time); |
|
208 } |
|
209 |
|
210 /** |
|
211 * Empty cache for a specific template |
|
212 * |
|
213 * @param Smarty $smarty Smarty object |
|
214 * @param string $resource_name template name |
|
215 * @param string $cache_id cache id |
|
216 * @param string $compile_id compile id |
|
217 * @param integer $exp_time expiration time (number of seconds, not timestamp) |
|
218 * |
|
219 * @return integer number of cache files deleted |
|
220 */ |
|
221 public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time) { |
|
222 $this->cache = array(); |
|
223 $cache_name = null; |
|
224 |
|
225 if (isset($resource_name)) { |
|
226 $_save_stat = $smarty->caching; |
|
227 $smarty->caching = true; |
|
228 $tpl = new $smarty->template_class($resource_name, $smarty); |
|
229 $smarty->caching = $_save_stat; |
|
230 |
|
231 if ($tpl->source->exists) { |
|
232 $cache_name = $tpl->source->name; |
|
233 } else { |
|
234 return 0; |
|
235 } |
|
236 // remove from template cache |
|
237 if ($smarty->allow_ambiguous_resources) { |
|
238 $_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id; |
|
239 } else { |
|
240 $_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id; |
|
241 } |
|
242 if (isset($_templateId[150])) { |
|
243 $_templateId = sha1($_templateId); |
|
244 } |
|
245 unset($smarty->template_objects[$_templateId]); |
|
246 // template object no longer needed |
|
247 unset($tpl); |
|
248 } |
|
249 |
|
250 return $this->delete($cache_name, $cache_id, $compile_id, $exp_time); |
|
251 } |
|
252 |
|
253 /** |
|
254 * Check is cache is locked for this template |
|
255 * |
|
256 * @param Smarty $smarty Smarty object |
|
257 * @param Smarty_Template_Cached $cached cached object |
|
258 * |
|
259 * @return boolean true or false if cache is locked |
|
260 */ |
|
261 public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached) { |
|
262 $id = $cached->lock_id; |
|
263 $name = $cached->source->name . '.lock'; |
|
264 |
|
265 $mtime = $this->fetchTimestamp($id, $name, $cached->cache_id, $cached->compile_id); |
|
266 if ($mtime === null) { |
|
267 $this->fetch($id, $name, $cached->cache_id, $cached->compile_id, $content, $mtime); |
|
268 } |
|
269 return $mtime && ($t = time()) - $mtime < $smarty->locking_timeout; |
|
270 } |
|
271 |
|
272 /** |
|
273 * Lock cache for this template |
|
274 * |
|
275 * @param Smarty $smarty Smarty object |
|
276 * @param Smarty_Template_Cached $cached cached object |
|
277 * |
|
278 * @return bool|void |
|
279 */ |
|
280 public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached) { |
|
281 $cached->is_locked = true; |
|
282 $id = $cached->lock_id; |
|
283 $name = $cached->source->name . '.lock'; |
|
284 $this->save($id, $name, $cached->cache_id, $cached->compile_id, $smarty->locking_timeout, ''); |
|
285 } |
|
286 |
|
287 /** |
|
288 * Unlock cache for this template |
|
289 * |
|
290 * @param Smarty $smarty Smarty object |
|
291 * @param Smarty_Template_Cached $cached cached object |
|
292 * |
|
293 * @return bool|void |
|
294 */ |
|
295 public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached) { |
|
296 $cached->is_locked = false; |
|
297 $name = $cached->source->name . '.lock'; |
|
298 $this->delete($name, $cached->cache_id, $cached->compile_id, null); |
|
299 } |
|
300 } |