smarty_internal_utility.php (12126B)
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 /** 39 * private constructor to prevent calls creation of new instances 40 */ 41 final private function __construct() 42 { 43 // intentionally left blank 44 } 45 46 /** 47 * Compile all template files 48 * 49 * @param string $extension template file name extension 50 * @param bool $force_compile force all to recompile 51 * @param int $time_limit set maximum execution time 52 * @param int $max_errors set maximum allowed errors 53 * @param Smarty $smarty Smarty instance 54 * 55 * @return integer number of template files compiled 56 */ 57 public static function compileAllTemplates($extension, $force_compile, $time_limit, $max_errors, Smarty $smarty) 58 { 59 // switch off time limit 60 if (function_exists('set_time_limit')) { 61 @set_time_limit($time_limit); 62 } 63 $smarty->force_compile = $force_compile; 64 $_count = 0; 65 $_error_count = 0; 66 // loop over array of template directories 67 foreach ($smarty->getTemplateDir() as $_dir) { 68 $_compileDirs = new RecursiveDirectoryIterator($_dir); 69 $_compile = new RecursiveIteratorIterator($_compileDirs); 70 foreach ($_compile as $_fileinfo) { 71 $_file = $_fileinfo->getFilename(); 72 if (substr(basename($_fileinfo->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false) { 73 continue; 74 } 75 if (!substr_compare($_file, $extension, - strlen($extension)) == 0) { 76 continue; 77 } 78 if ($_fileinfo->getPath() == substr($_dir, 0, - 1)) { 79 $_template_file = $_file; 80 } else { 81 $_template_file = substr($_fileinfo->getPath(), strlen($_dir)) . DS . $_file; 82 } 83 echo '<br>', $_dir, '---', $_template_file; 84 flush(); 85 $_start_time = microtime(true); 86 try { 87 $_tpl = $smarty->createTemplate($_template_file, null, null, null, false); 88 if ($_tpl->mustCompile()) { 89 $_tpl->compileTemplateSource(); 90 $_count ++; 91 echo ' compiled in ', microtime(true) - $_start_time, ' seconds'; 92 flush(); 93 } else { 94 echo ' is up to date'; 95 flush(); 96 } 97 } 98 catch (Exception $e) { 99 echo 'Error: ', $e->getMessage(), "<br><br>"; 100 $_error_count ++; 101 } 102 // free memory 103 $smarty->template_objects = array(); 104 $_tpl->smarty->template_objects = array(); 105 $_tpl = null; 106 if ($max_errors !== null && $_error_count == $max_errors) { 107 echo '<br><br>too many errors'; 108 exit(); 109 } 110 } 111 } 112 113 return $_count; 114 } 115 116 /** 117 * Compile all config files 118 * 119 * @param string $extension config file name extension 120 * @param bool $force_compile force all to recompile 121 * @param int $time_limit set maximum execution time 122 * @param int $max_errors set maximum allowed errors 123 * @param Smarty $smarty Smarty instance 124 * 125 * @return integer number of config files compiled 126 */ 127 public static function compileAllConfig($extension, $force_compile, $time_limit, $max_errors, Smarty $smarty) 128 { 129 // switch off time limit 130 if (function_exists('set_time_limit')) { 131 @set_time_limit($time_limit); 132 } 133 $smarty->force_compile = $force_compile; 134 $_count = 0; 135 $_error_count = 0; 136 // loop over array of template directories 137 foreach ($smarty->getConfigDir() as $_dir) { 138 $_compileDirs = new RecursiveDirectoryIterator($_dir); 139 $_compile = new RecursiveIteratorIterator($_compileDirs); 140 foreach ($_compile as $_fileinfo) { 141 $_file = $_fileinfo->getFilename(); 142 if (substr(basename($_fileinfo->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false) { 143 continue; 144 } 145 if (!substr_compare($_file, $extension, - strlen($extension)) == 0) { 146 continue; 147 } 148 if ($_fileinfo->getPath() == substr($_dir, 0, - 1)) { 149 $_config_file = $_file; 150 } else { 151 $_config_file = substr($_fileinfo->getPath(), strlen($_dir)) . DS . $_file; 152 } 153 echo '<br>', $_dir, '---', $_config_file; 154 flush(); 155 $_start_time = microtime(true); 156 try { 157 $_config = new Smarty_Internal_Config($_config_file, $smarty); 158 if ($_config->mustCompile()) { 159 $_config->compileConfigSource(); 160 $_count ++; 161 echo ' compiled in ', microtime(true) - $_start_time, ' seconds'; 162 flush(); 163 } else { 164 echo ' is up to date'; 165 flush(); 166 } 167 } 168 catch (Exception $e) { 169 echo 'Error: ', $e->getMessage(), "<br><br>"; 170 $_error_count ++; 171 } 172 if ($max_errors !== null && $_error_count == $max_errors) { 173 echo '<br><br>too many errors'; 174 exit(); 175 } 176 } 177 } 178 179 return $_count; 180 } 181 182 /** 183 * Delete compiled template file 184 * 185 * @param string $resource_name template name 186 * @param string $compile_id compile id 187 * @param integer $exp_time expiration time 188 * @param Smarty $smarty Smarty instance 189 * 190 * @return integer number of template files deleted 191 */ 192 public static function clearCompiledTemplate($resource_name, $compile_id, $exp_time, Smarty $smarty) 193 { 194 $_compile_dir = realpath($smarty->getCompileDir()) . '/'; 195 if ($_compile_dir == '/') { //We should never want to delete this! 196 return 0; 197 } 198 $_compile_id = isset($compile_id) ? preg_replace('![^\w\|]+!', '_', $compile_id) : null; 199 $_dir_sep = $smarty->use_sub_dirs ? '/' : '^'; 200 if (isset($resource_name)) { 201 $_save_stat = $smarty->caching; 202 $smarty->caching = false; 203 $tpl = new $smarty->template_class($resource_name, $smarty); 204 $smarty->caching = $_save_stat; 205 206 // remove from template cache 207 $tpl->source; // have the template registered before unset() 208 if ($smarty->allow_ambiguous_resources) { 209 $_templateId = $tpl->source->unique_resource . $tpl->cache_id . $tpl->compile_id; 210 } else { 211 $_templateId = $smarty->joined_template_dir . '#' . $resource_name . $tpl->cache_id . $tpl->compile_id; 212 } 213 if (isset($_templateId[150])) { 214 $_templateId = sha1($_templateId); 215 } 216 unset($smarty->template_objects[$_templateId]); 217 218 if ($tpl->source->exists) { 219 $_resource_part_1 = basename(str_replace('^', '/', $tpl->compiled->filepath)); 220 $_resource_part_1_length = strlen($_resource_part_1); 221 } else { 222 return 0; 223 } 224 225 $_resource_part_2 = str_replace('.php', '.cache.php', $_resource_part_1); 226 $_resource_part_2_length = strlen($_resource_part_2); 227 } 228 $_dir = $_compile_dir; 229 if ($smarty->use_sub_dirs && isset($_compile_id)) { 230 $_dir .= $_compile_id . $_dir_sep; 231 } 232 if (isset($_compile_id)) { 233 $_compile_id_part = str_replace('\\', '/', $_compile_dir . $_compile_id . $_dir_sep); 234 $_compile_id_part_length = strlen($_compile_id_part); 235 } 236 $_count = 0; 237 try { 238 $_compileDirs = new RecursiveDirectoryIterator($_dir); 239 // NOTE: UnexpectedValueException thrown for PHP >= 5.3 240 } 241 catch (Exception $e) { 242 return 0; 243 } 244 $_compile = new RecursiveIteratorIterator($_compileDirs, RecursiveIteratorIterator::CHILD_FIRST); 245 foreach ($_compile as $_file) { 246 if (substr(basename($_file->getPathname()), 0, 1) == '.' || strpos($_file, '.svn') !== false) { 247 continue; 248 } 249 250 $_filepath = str_replace('\\', '/', (string) $_file); 251 252 if ($_file->isDir()) { 253 if (!$_compile->isDot()) { 254 // delete folder if empty 255 @rmdir($_file->getPathname()); 256 } 257 } else { 258 $unlink = false; 259 if ((!isset($_compile_id) || (isset($_filepath[$_compile_id_part_length]) && $a = !strncmp($_filepath, $_compile_id_part, $_compile_id_part_length))) 260 && (!isset($resource_name) 261 || (isset($_filepath[$_resource_part_1_length]) 262 && substr_compare($_filepath, $_resource_part_1, - $_resource_part_1_length, $_resource_part_1_length) == 0) 263 || (isset($_filepath[$_resource_part_2_length]) 264 && substr_compare($_filepath, $_resource_part_2, - $_resource_part_2_length, $_resource_part_2_length) == 0)) 265 ) { 266 if (isset($exp_time)) { 267 if (time() - @filemtime($_filepath) >= $exp_time) { 268 $unlink = true; 269 } 270 } else { 271 $unlink = true; 272 } 273 } 274 275 if ($unlink && @unlink($_filepath)) { 276 $_count ++; 277 } 278 } 279 } 280 // clear compiled cache 281 Smarty_Resource::$sources = array(); 282 Smarty_Resource::$compileds = array(); 283 284 return $_count; 285 } 286 287 /** 288 * Return array of tag/attributes of all tags used by an template 289 * 290 * @param Smarty_Internal_Template $template 291 * 292 * @throws Exception 293 * @throws SmartyException 294 * @return array of tag/attributes 295 */ 296 public static function getTags(Smarty_Internal_Template $template) 297 { 298 $template->smarty->get_used_tags = true; 299 $template->compileTemplateSource(); 300 301 return $template->used_tags; 302 } 303 }