|
1 <?php |
|
2 /** |
|
3 * Project: Smarty: the PHP compiling template engine |
|
4 * File: smarty_internal_utility.php |
|
5 * SVN: $Id: $ |
|
6 * This library is free software; you can redistribute it and/or |
|
7 * modify it under the terms of the GNU Lesser General Public |
|
8 * License as published by the Free Software Foundation; either |
|
9 * version 2.1 of the License, or (at your option) any later version. |
|
10 * This library is distributed in the hope that it will be useful, |
|
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of |
|
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
|
13 * Lesser General Public License for more details. |
|
14 * You should have received a copy of the GNU Lesser General Public |
|
15 * License along with this library; if not, write to the Free Software |
|
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
17 * For questions, help, comments, discussion, etc., please join the |
|
18 * Smarty mailing list. Send a blank e-mail to |
|
19 * smarty-discussion-subscribe@googlegroups.com |
|
20 * |
|
21 * @link http://www.smarty.net/ |
|
22 * @copyright 2008 New Digital Group, Inc. |
|
23 * @author Monte Ohrt <monte at ohrt dot com> |
|
24 * @author Uwe Tews |
|
25 * @package Smarty |
|
26 * @subpackage PluginsInternal |
|
27 * @version 3-SVN$Rev: 3286 $ |
|
28 */ |
|
29 |
|
30 /** |
|
31 * Utility class |
|
32 * |
|
33 * @package Smarty |
|
34 * @subpackage Security |
|
35 */ |
|
36 class Smarty_Internal_Utility { |
|
37 /** |
|
38 * private constructor to prevent calls creation of new instances |
|
39 */ |
|
40 final private function __construct() { |
|
41 // intentionally left blank |
|
42 } |
|
43 |
|
44 /** |
|
45 * Compile all template files |
|
46 * |
|
47 * @param string $extension template file name extension |
|
48 * @param bool $force_compile force all to recompile |
|
49 * @param int $time_limit set maximum execution time |
|
50 * @param int $max_errors set maximum allowed errors |
|
51 * @param Smarty $smarty Smarty instance |
|
52 * |
|
53 * @return integer number of template files compiled |
|
54 */ |
|
55 public static function compileAllTemplates($extension, $force_compile, $time_limit, $max_errors, Smarty $smarty) { |
|
56 // switch off time limit |
|
57 if (function_exists('set_time_limit')) { |
|
58 @set_time_limit($time_limit); |
|
59 } |
|
60 $smarty->force_compile = $force_compile; |
|
61 $_count = 0; |
|
62 $_error_count = 0; |
|
63 // loop over array of template directories |
|
64 foreach ($smarty->getTemplateDir() as $_dir) { |
|
65 $_compileDirs = new RecursiveDirectoryIterator($_dir); |
|
66 $_compile = new RecursiveIteratorIterator($_compileDirs); |
|
67 foreach ($_compile as $_fileinfo) { |
|
68 $_file = $_fileinfo->getFilename(); |
|
69 if (substr(basename($_fileinfo->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false) { |
|
70 continue; |
|
71 } |
|
72 if (!substr_compare($_file, $extension, -strlen($extension)) == 0) { |
|
73 continue; |
|
74 } |
|
75 if ($_fileinfo->getPath() == substr($_dir, 0, -1)) { |
|
76 $_template_file = $_file; |
|
77 } else { |
|
78 $_template_file = substr($_fileinfo->getPath(), strlen($_dir)) . DS . $_file; |
|
79 } |
|
80 echo '<br>', $_dir, '---', $_template_file; |
|
81 flush(); |
|
82 $_start_time = microtime(true); |
|
83 try { |
|
84 $_tpl = $smarty->createTemplate($_template_file, null, null, null, false); |
|
85 if ($_tpl->mustCompile()) { |
|
86 $_tpl->compileTemplateSource(); |
|
87 $_count++; |
|
88 echo ' compiled in ', microtime(true) - $_start_time, ' seconds'; |
|
89 flush(); |
|
90 } else { |
|
91 echo ' is up to date'; |
|
92 flush(); |
|
93 } |
|
94 } catch (Exception $e) { |
|
95 echo 'Error: ', $e->getMessage(), "<br><br>"; |
|
96 $_error_count++; |
|
97 } |
|
98 // free memory |
|
99 $smarty->template_objects = array(); |
|
100 $_tpl->smarty->template_objects = array(); |
|
101 $_tpl = null; |
|
102 if ($max_errors !== null && $_error_count == $max_errors) { |
|
103 echo '<br><br>too many errors'; |
|
104 exit(); |
|
105 } |
|
106 } |
|
107 } |
|
108 |
|
109 return $_count; |
|
110 } |
|
111 |
|
112 /** |
|
113 * Compile all config files |
|
114 * |
|
115 * @param string $extension config file name extension |
|
116 * @param bool $force_compile force all to recompile |
|
117 * @param int $time_limit set maximum execution time |
|
118 * @param int $max_errors set maximum allowed errors |
|
119 * @param Smarty $smarty Smarty instance |
|
120 * |
|
121 * @return integer number of config files compiled |
|
122 */ |
|
123 public static function compileAllConfig($extension, $force_compile, $time_limit, $max_errors, Smarty $smarty) { |
|
124 // switch off time limit |
|
125 if (function_exists('set_time_limit')) { |
|
126 @set_time_limit($time_limit); |
|
127 } |
|
128 $smarty->force_compile = $force_compile; |
|
129 $_count = 0; |
|
130 $_error_count = 0; |
|
131 // loop over array of template directories |
|
132 foreach ($smarty->getConfigDir() as $_dir) { |
|
133 $_compileDirs = new RecursiveDirectoryIterator($_dir); |
|
134 $_compile = new RecursiveIteratorIterator($_compileDirs); |
|
135 foreach ($_compile as $_fileinfo) { |
|
136 $_file = $_fileinfo->getFilename(); |
|
137 if (substr(basename($_fileinfo->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false) { |
|
138 continue; |
|
139 } |
|
140 if (!substr_compare($_file, $extension, -strlen($extension)) == 0) { |
|
141 continue; |
|
142 } |
|
143 if ($_fileinfo->getPath() == substr($_dir, 0, -1)) { |
|
144 $_config_file = $_file; |
|
145 } else { |
|
146 $_config_file = substr($_fileinfo->getPath(), strlen($_dir)) . DS . $_file; |
|
147 } |
|
148 echo '<br>', $_dir, '---', $_config_file; |
|
149 flush(); |
|
150 $_start_time = microtime(true); |
|
151 try { |
|
152 $_config = new Smarty_Internal_Config($_config_file, $smarty); |
|
153 if ($_config->mustCompile()) { |
|
154 $_config->compileConfigSource(); |
|
155 $_count++; |
|
156 echo ' compiled in ', microtime(true) - $_start_time, ' seconds'; |
|
157 flush(); |
|
158 } else { |
|
159 echo ' is up to date'; |
|
160 flush(); |
|
161 } |
|
162 } catch (Exception $e) { |
|
163 echo 'Error: ', $e->getMessage(), "<br><br>"; |
|
164 $_error_count++; |
|
165 } |
|
166 if ($max_errors !== null && $_error_count == $max_errors) { |
|
167 echo '<br><br>too many errors'; |
|
168 exit(); |
|
169 } |
|
170 } |
|
171 } |
|
172 |
|
173 return $_count; |
|
174 } |
|
175 |
|
176 /** |
|
177 * Delete compiled template file |
|
178 * |
|
179 * @param string $resource_name template name |
|
180 * @param string $compile_id compile id |
|
181 * @param integer $exp_time expiration time |
|
182 * @param Smarty $smarty Smarty instance |
|
183 * |
|
184 * @return integer number of template files deleted |
|
185 */ |
|
186 public static function clearCompiledTemplate($resource_name, $compile_id, $exp_time, Smarty $smarty) { |
|
187 $_compile_dir = realpath($smarty->getCompileDir()) . '/'; |
|
188 if ($_compile_dir == '/') { //We should never want to delete this! |
|
189 return 0; |
|
190 } |
|
191 $_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null; |
|
192 $_dir_sep = $smarty->use_sub_dirs ? '/' : '^'; |
|
193 if (isset($resource_name)) { |
|
194 $_save_stat = $smarty->caching; |
|
195 $smarty->caching = false; |
|
196 $tpl = new $smarty->template_class($resource_name, $smarty); |
|
197 $smarty->caching = $_save_stat; |
|
198 |
|
199 // remove from template cache |
|
200 $tpl->source; // have the template registered before unset() |
|
201 if ($smarty->allow_ambiguous_resources) { |
|
202 $_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id; |
|
203 } else { |
|
204 $_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id; |
|
205 } |
|
206 if (isset($_templateId[150])) { |
|
207 $_templateId = sha1($_templateId); |
|
208 } |
|
209 unset($smarty->template_objects[$_templateId]); |
|
210 |
|
211 if ($tpl->source->exists) { |
|
212 $_resource_part_1 = basename(str_replace('^', '/', $tpl->compiled->filepath)); |
|
213 $_resource_part_1_length = strlen($_resource_part_1); |
|
214 } else { |
|
215 return 0; |
|
216 } |
|
217 |
|
218 $_resource_part_2 = str_replace('.php', '.cache.php', $_resource_part_1); |
|
219 $_resource_part_2_length = strlen($_resource_part_2); |
|
220 } |
|
221 $_dir = $_compile_dir; |
|
222 if ($smarty->use_sub_dirs && isset($_compile_id)) { |
|
223 $_dir .= $_compile_id . $_dir_sep; |
|
224 } |
|
225 if (isset($_compile_id)) { |
|
226 $_compile_id_part = str_replace('\\', '/', $_compile_dir . $_compile_id . $_dir_sep); |
|
227 $_compile_id_part_length = strlen($_compile_id_part); |
|
228 } |
|
229 $_count = 0; |
|
230 try { |
|
231 $_compileDirs = new RecursiveDirectoryIterator($_dir); |
|
232 // NOTE: UnexpectedValueException thrown for PHP >= 5.3 |
|
233 } catch (Exception $e) { |
|
234 return 0; |
|
235 } |
|
236 $_compile = new RecursiveIteratorIterator($_compileDirs, RecursiveIteratorIterator::CHILD_FIRST); |
|
237 foreach ($_compile as $_file) { |
|
238 if (substr(basename($_file->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false) { |
|
239 continue; |
|
240 } |
|
241 |
|
242 $_filepath = str_replace('\\', '/', (string)$_file); |
|
243 |
|
244 if ($_file->isDir()) { |
|
245 if (!$_compile->isDot()) { |
|
246 // delete folder if empty |
|
247 @rmdir($_file->getPathname()); |
|
248 } |
|
249 } else { |
|
250 $unlink = false; |
|
251 if ((!isset($_compile_id) || (isset($_filepath[$_compile_id_part_length]) && $a = !strncmp($_filepath, $_compile_id_part, $_compile_id_part_length))) |
|
252 && (!isset($resource_name) |
|
253 || (isset($_filepath[$_resource_part_1_length]) |
|
254 && substr_compare($_filepath, $_resource_part_1, -$_resource_part_1_length, $_resource_part_1_length) == 0) |
|
255 || (isset($_filepath[$_resource_part_2_length]) |
|
256 && substr_compare($_filepath, $_resource_part_2, -$_resource_part_2_length, $_resource_part_2_length) == 0)) |
|
257 ) { |
|
258 if (isset($exp_time)) { |
|
259 if (time() - @filemtime($_filepath) >= $exp_time) { |
|
260 $unlink = true; |
|
261 } |
|
262 } else { |
|
263 $unlink = true; |
|
264 } |
|
265 } |
|
266 |
|
267 if ($unlink && @unlink($_filepath)) { |
|
268 $_count++; |
|
269 } |
|
270 } |
|
271 } |
|
272 // clear compiled cache |
|
273 Smarty_Resource::$sources = array(); |
|
274 Smarty_Resource::$compileds = array(); |
|
275 |
|
276 return $_count; |
|
277 } |
|
278 |
|
279 /** |
|
280 * Return array of tag/attributes of all tags used by an template |
|
281 * |
|
282 * @param Smarty_Internal_Template $template |
|
283 * |
|
284 * @throws Exception |
|
285 * @throws SmartyException |
|
286 * @return array of tag/attributes |
|
287 */ |
|
288 public static function getTags(Smarty_Internal_Template $template) { |
|
289 $template->smarty->get_used_tags = true; |
|
290 $template->compileTemplateSource(); |
|
291 |
|
292 return $template->used_tags; |
|
293 } |
|
294 } |