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