source: trunk/include/smarty/libs/sysplugins/smarty_internal_cacheresource_file.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: 10.2 KB
Line 
1<?php
2/**
3 * Smarty Internal Plugin CacheResource File
4 *
5 * @package Smarty
6 * @subpackage Cacher
7 * @author Uwe Tews
8 * @author Rodney Rehm
9 */
10
11/**
12 * This class does contain all necessary methods for the HTML cache on file system
13 *
14 * Implements the file system as resource for the HTML cache Version ussing nocache inserts.
15 *
16 * @package Smarty
17 * @subpackage Cacher
18 */
19class Smarty_Internal_CacheResource_File extends Smarty_CacheResource {
20
21    /**
22     * populate Cached Object with meta data from Resource
23     *
24     * @param Smarty_Template_Cached   $cached    cached object
25     * @param Smarty_Internal_Template $_template template object
26     * @return void
27     */
28    public function populate(Smarty_Template_Cached $cached, Smarty_Internal_Template $_template)
29    {
30        $_source_file_path = str_replace(':', '.', $_template->source->filepath);
31        $_cache_id = isset($_template->cache_id) ? preg_replace('![^\w\|]+!', '_', $_template->cache_id) : null;
32        $_compile_id = isset($_template->compile_id) ? preg_replace('![^\w\|]+!', '_', $_template->compile_id) : null;
33        $_filepath = $_template->source->uid;
34        // if use_sub_dirs, break file into directories
35        if ($_template->smarty->use_sub_dirs) {
36            $_filepath = substr($_filepath, 0, 2) . DS
37                . substr($_filepath, 2, 2) . DS
38                . substr($_filepath, 4, 2) . DS
39                . $_filepath;
40        }
41        $_compile_dir_sep = $_template->smarty->use_sub_dirs ? DS : '^';
42        if (isset($_cache_id)) {
43            $_cache_id = str_replace('|', $_compile_dir_sep, $_cache_id) . $_compile_dir_sep;
44        } else {
45            $_cache_id = '';
46        }
47        if (isset($_compile_id)) {
48            $_compile_id = $_compile_id . $_compile_dir_sep;
49        } else {
50            $_compile_id = '';
51        }
52        $_cache_dir = $_template->smarty->getCacheDir();
53        if ($_template->smarty->cache_locking) {
54            // create locking file name
55            // relative file name?
56            if (!preg_match('/^([\/\\\\]|[a-zA-Z]:[\/\\\\])/', $_cache_dir)) {
57                $_lock_dir = rtrim(getcwd(), '/\\') . DS . $_cache_dir;
58            } else {
59                $_lock_dir = $_cache_dir;
60            }
61            $cached->lock_id = $_lock_dir.sha1($_cache_id.$_compile_id.$_template->source->uid).'.lock';
62        }
63        $cached->filepath = $_cache_dir . $_cache_id . $_compile_id . $_filepath . '.' . basename($_source_file_path) . '.php';
64        $cached->timestamp = @filemtime($cached->filepath);
65        $cached->exists = !!$cached->timestamp;
66    }
67
68    /**
69     * populate Cached Object with timestamp and exists from Resource
70     *
71     * @param Smarty_Template_Cached $cached cached object
72     * @return void
73     */
74    public function populateTimestamp(Smarty_Template_Cached $cached)
75    {
76        $cached->timestamp = @filemtime($cached->filepath);
77        $cached->exists = !!$cached->timestamp;
78    }
79
80    /**
81     * Read the cached template and process its header
82     *
83     * @param Smarty_Internal_Template $_template template object
84     * @param Smarty_Template_Cached $cached cached object
85     * @return booelan true or false if the cached content does not exist
86     */
87    public function process(Smarty_Internal_Template $_template, Smarty_Template_Cached $cached=null)
88    {
89        $_smarty_tpl = $_template;
90        return @include $_template->cached->filepath;
91    }
92
93    /**
94     * Write the rendered template output to cache
95     *
96     * @param Smarty_Internal_Template $_template template object
97     * @param string                   $content   content to cache
98     * @return boolean success
99     */
100    public function writeCachedContent(Smarty_Internal_Template $_template, $content)
101    {
102        if (Smarty_Internal_Write_File::writeFile($_template->cached->filepath, $content, $_template->smarty) === true) {
103            $_template->cached->timestamp = @filemtime($_template->cached->filepath);
104            $_template->cached->exists = !!$_template->cached->timestamp;
105            if ($_template->cached->exists) {
106                return true;
107            }
108        }
109        return false;
110    }
111
112    /**
113     * Empty cache
114     *
115     * @param Smarty_Internal_Template $_template template object
116     * @param integer                  $exp_time  expiration time (number of seconds, not timestamp)
117     * @return integer number of cache files deleted
118     */
119    public function clearAll(Smarty $smarty, $exp_time = null)
120    {
121        return $this->clear($smarty, null, null, null, $exp_time);
122    }
123
124    /**
125     * Empty cache for a specific template
126     *
127     * @param Smarty  $_template     template object
128     * @param string  $resource_name template name
129     * @param string  $cache_id      cache id
130     * @param string  $compile_id    compile id
131     * @param integer $exp_time      expiration time (number of seconds, not timestamp)
132     * @return integer number of cache files deleted
133    */
134    public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time)
135    {
136        $_cache_id = isset($cache_id) ? preg_replace('![^\w\|]+!', '_', $cache_id) : null;
137        $_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null;
138        $_dir_sep = $smarty->use_sub_dirs ? '/' : '^';
139        $_compile_id_offset = $smarty->use_sub_dirs ? 3 : 0;
140        $_dir = $smarty->getCacheDir();
141        $_dir_length = strlen($_dir);
142        if (isset($_cache_id)) {
143            $_cache_id_parts = explode('|', $_cache_id);
144            $_cache_id_parts_count = count($_cache_id_parts);
145            if ($smarty->use_sub_dirs) {
146                foreach ($_cache_id_parts as $id_part) {
147                    $_dir .= $id_part . DS;
148                }
149            }
150        }
151        if (isset($resource_name)) {
152            $_save_stat = $smarty->caching;
153            $smarty->caching = true;
154            $tpl = new $smarty->template_class($resource_name, $smarty);
155            $smarty->caching = $_save_stat;
156
157            // remove from template cache
158            $tpl->source; // have the template registered before unset()
159            if ($smarty->allow_ambiguous_resources) {
160                $_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id;
161            } else {
162                $_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id;
163            }
164            if (isset($_templateId[150])) {
165                $_templateId = sha1($_templateId);
166            }
167            unset($smarty->template_objects[$_templateId]);
168
169            if ($tpl->source->exists) {
170                $_resourcename_parts = basename(str_replace('^', '/', $tpl->cached->filepath));
171            } else {
172                return 0;
173            }
174        }
175        $_count = 0;
176        $_time = time();
177        if (file_exists($_dir)) {
178            $_cacheDirs = new RecursiveDirectoryIterator($_dir);
179            $_cache = new RecursiveIteratorIterator($_cacheDirs, RecursiveIteratorIterator::CHILD_FIRST);
180            foreach ($_cache as $_file) {
181                if (substr(basename($_file->getPathname()),0,1) == '.' || strpos($_file, '.svn') !== false) continue;
182                // directory ?
183                if ($_file->isDir()) {
184                    if (!$_cache->isDot()) {
185                        // delete folder if empty
186                        @rmdir($_file->getPathname());
187                    }
188                } else {
189                    $_parts = explode($_dir_sep, str_replace('\\', '/', substr((string)$_file, $_dir_length)));
190                    $_parts_count = count($_parts);
191                    // check name
192                    if (isset($resource_name)) {
193                        if ($_parts[$_parts_count-1] != $_resourcename_parts) {
194                            continue;
195                        }
196                    }
197                    // check compile id
198                    if (isset($_compile_id) && (!isset($_parts[$_parts_count-2 - $_compile_id_offset]) || $_parts[$_parts_count-2 - $_compile_id_offset] != $_compile_id)) {
199                        continue;
200                    }
201                    // check cache id
202                    if (isset($_cache_id)) {
203                        // count of cache id parts
204                        $_parts_count = (isset($_compile_id)) ? $_parts_count - 2 - $_compile_id_offset : $_parts_count - 1 - $_compile_id_offset;
205                        if ($_parts_count < $_cache_id_parts_count) {
206                            continue;
207                        }
208                        for ($i = 0; $i < $_cache_id_parts_count; $i++) {
209                            if ($_parts[$i] != $_cache_id_parts[$i]) continue 2;
210                        }
211                    }
212                    // expired ?
213                    if (isset($exp_time) && $_time - @filemtime($_file) < $exp_time) {
214                        continue;
215                    }
216                    $_count += @unlink((string) $_file) ? 1 : 0;
217                }
218            }
219        }
220        return $_count;
221    }
222
223    /**
224     * Check is cache is locked for this template
225     *
226     * @param Smarty $smarty Smarty object
227     * @param Smarty_Template_Cached $cached cached object
228     * @return booelan true or false if cache is locked
229     */
230    public function hasLock(Smarty $smarty, Smarty_Template_Cached $cached)
231    {
232        if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
233            clearstatcache(true, $cached->lock_id);
234        } else {
235            clearstatcache();
236        }
237        $t = @filemtime($cached->lock_id);
238        return $t && (time() - $t < $smarty->locking_timeout);
239    }
240
241    /**
242     * Lock cache for this template
243     *
244     * @param Smarty $smarty Smarty object
245     * @param Smarty_Template_Cached $cached cached object
246     */
247    public function acquireLock(Smarty $smarty, Smarty_Template_Cached $cached)
248    {
249        $cached->is_locked = true;
250        touch($cached->lock_id);
251    }
252
253    /**
254     * Unlock cache for this template
255     *
256     * @param Smarty $smarty Smarty object
257     * @param Smarty_Template_Cached $cached cached object
258     */
259    public function releaseLock(Smarty $smarty, Smarty_Template_Cached $cached)
260    {
261        $cached->is_locked = false;
262        @unlink($cached->lock_id);
263    }
264}
265
266?>
Note: See TracBrowser for help on using the repository browser.