1<?php 2 3/** 4 * Smarty cache resource file clear method 5 * 6 * @package Smarty 7 * @subpackage PluginsInternal 8 * @author Uwe Tews 9 */ 10 11/** 12 * Smarty Internal Runtime Cache Resource File Class 13 * 14 * @package Smarty 15 * @subpackage PluginsInternal 16 */ 17class Smarty_Internal_Runtime_CacheResourceFile 18{ 19 /** 20 * Empty cache for a specific template 21 * 22 * @param Smarty $smarty 23 * @param string $resource_name template name 24 * @param string $cache_id cache id 25 * @param string $compile_id compile id 26 * @param integer $exp_time expiration time (number of seconds, not timestamp) 27 * 28 * @return integer number of cache files deleted 29 */ 30 public function clear(Smarty $smarty, $resource_name, $cache_id, $compile_id, $exp_time) 31 { 32 $_cache_id = isset($cache_id) ? preg_replace('![^\w\|]+!', '_', $cache_id) : null; 33 $_compile_id = isset($compile_id) ? preg_replace('![^\w]+!', '_', $compile_id) : null; 34 $_dir_sep = $smarty->use_sub_dirs ? '/' : '^'; 35 $_compile_id_offset = $smarty->use_sub_dirs ? 3 : 0; 36 $_dir = $smarty->getCacheDir(); 37 if ($_dir == '/') { //We should never want to delete this! 38 return 0; 39 } 40 $_dir_length = strlen($_dir); 41 if (isset($_cache_id)) { 42 $_cache_id_parts = explode('|', $_cache_id); 43 $_cache_id_parts_count = count($_cache_id_parts); 44 if ($smarty->use_sub_dirs) { 45 foreach ($_cache_id_parts as $id_part) { 46 $_dir .= $id_part . $smarty->ds; 47 } 48 } 49 } 50 if (isset($resource_name)) { 51 $_save_stat = $smarty->caching; 52 $smarty->caching = true; 53 $tpl = new $smarty->template_class($resource_name, $smarty); 54 $smarty->caching = $_save_stat; 55 56 // remove from template cache 57 $tpl->source; // have the template registered before unset() 58 59 if ($tpl->source->exists) { 60 $_resourcename_parts = basename(str_replace('^', '/', $tpl->cached->filepath)); 61 } else { 62 return 0; 63 } 64 } 65 $_count = 0; 66 $_time = time(); 67 if (file_exists($_dir)) { 68 $_cacheDirs = new RecursiveDirectoryIterator($_dir); 69 $_cache = new RecursiveIteratorIterator($_cacheDirs, RecursiveIteratorIterator::CHILD_FIRST); 70 foreach ($_cache as $_file) { 71 if (substr(basename($_file->getPathname()), 0, 1) == '.') { 72 continue; 73 } 74 $_filepath = (string) $_file; 75 // directory ? 76 if ($_file->isDir()) { 77 if (!$_cache->isDot()) { 78 // delete folder if empty 79 @rmdir($_file->getPathname()); 80 } 81 } else { 82 // delete only php files 83 if (substr($_filepath, -4) !== '.php') { 84 continue; 85 } 86 $_parts = explode($_dir_sep, str_replace('\\', '/', substr($_filepath, $_dir_length))); 87 $_parts_count = count($_parts); 88 // check name 89 if (isset($resource_name)) { 90 if ($_parts[ $_parts_count - 1 ] != $_resourcename_parts) { 91 continue; 92 } 93 } 94 // check compile id 95 if (isset($_compile_id) && (!isset($_parts[ $_parts_count - 2 - $_compile_id_offset ]) || 96 $_parts[ $_parts_count - 2 - $_compile_id_offset ] != $_compile_id) 97 ) { 98 continue; 99 } 100 // check cache id 101 if (isset($_cache_id)) { 102 // count of cache id parts 103 $_parts_count = (isset($_compile_id)) ? $_parts_count - 2 - $_compile_id_offset : 104 $_parts_count - 1 - $_compile_id_offset; 105 if ($_parts_count < $_cache_id_parts_count) { 106 continue; 107 } 108 for ($i = 0; $i < $_cache_id_parts_count; $i ++) { 109 if ($_parts[ $i ] != $_cache_id_parts[ $i ]) { 110 continue 2; 111 } 112 } 113 } 114 // expired ? 115 if (isset($exp_time)) { 116 if ($exp_time < 0) { 117 preg_match('#\'cache_lifetime\' =>\s*(\d*)#', file_get_contents($_file), $match); 118 if ($_time < (@filemtime($_file) + $match[ 1 ])) { 119 continue; 120 } 121 } else { 122 if ($_time - @filemtime($_file) < $exp_time) { 123 continue; 124 } 125 } 126 } 127 $_count += @unlink($_filepath) ? 1 : 0; 128 if (function_exists('opcache_invalidate') && strlen(ini_get("opcache.restrict_api")) < 1) { 129 opcache_invalidate($_filepath, true); 130 } 131 } 132 } 133 } 134 return $_count; 135 } 136}