W3TCCache_File_Generic

Class Cache_File_Generic.

Defined (1)

The class is defined in the following location(s).

/Cache_File_Generic.php  
  1. class Cache_File_Generic extends Cache_File { 
  2. /** 
  3. * Expire 
  4. * @var integer 
  5. */ 
  6. var $_expire = 0; 
  7.  
  8. /** 
  9. * PHP5-style constructor 
  10. * @param array $config 
  11. */ 
  12. function __construct( $config = array() ) { 
  13. parent::__construct( $config ); 
  14.  
  15. $this->_expire = ( isset( $config['expire'] ) ? (int) $config['expire'] : 0 ); 
  16.  
  17. if ( !$this->_expire || $this->_expire > W3TC_CACHE_FILE_EXPIRE_MAX ) { 
  18. $this->_expire = W3TC_CACHE_FILE_EXPIRE_MAX; 
  19.  
  20. /** 
  21. * Sets data 
  22. * @param string $key 
  23. * @param string $var 
  24. * @param int $expire 
  25. * @param string $group Used to differentiate between groups of cache values 
  26. * @return boolean 
  27. */ 
  28. function set( $key, $var, $expire = 0, $group = '' ) { 
  29. $key = $this->get_item_key( $key ); 
  30. $sub_path = $this->_get_path( $key ); 
  31. $path = $this->_cache_dir . '/' . $sub_path; 
  32.  
  33. $dir = dirname( $path ); 
  34.  
  35. if ( !@is_dir( $dir ) ) { 
  36. if ( !Util_File::mkdir_from_safe( $dir, W3TC_CACHE_DIR ) ) 
  37. return false; 
  38.  
  39. $tmppath = $path . '.' . getmypid(); 
  40.  
  41. $fp = @fopen( $tmppath, 'w' ); 
  42. if ( !$fp ) 
  43. return false; 
  44.  
  45. if ( $this->_locking ) 
  46. @flock( $fp, LOCK_EX ); 
  47.  
  48. @fputs( $fp, $var['content'] ); 
  49. @fclose( $fp ); 
  50.  
  51. if ( $this->_locking ) 
  52. @flock( $fp, LOCK_UN ); 
  53.  
  54. // some hostings create files with restrictive permissions 
  55. // not allowing apache to read it later 
  56. @chmod( $path, 0644 ); 
  57.  
  58. if ( @filesize( $tmppath ) > 0 ) { 
  59. @unlink( $path ); 
  60. @rename( $tmppath, $path ); 
  61.  
  62. @unlink( $tmppath ); 
  63.  
  64. $old_entry_path = $path . '_old'; 
  65. @unlink( $old_entry_path ); 
  66.  
  67. if ( Util_Environment::is_apache() && isset( $var['headers'] ) && 
  68. isset( $var['headers']['Content-Type'] ) && 
  69. substr( $var['headers']['Content-Type'], 0, 8 ) == 'text/xml' ) { 
  70. file_put_contents( dirname( $path ) . '/.htaccess',  
  71. "<IfModule mod_mime.c>\n" . 
  72. " RemoveType .html_gzip\n" . 
  73. " AddType text/xml .html_gzip\n" . 
  74. " RemoveType .html\n" . 
  75. " AddType text/xml .html\n". 
  76. "</IfModule>" ); 
  77.  
  78. return true; 
  79.  
  80. /** 
  81. * Returns data 
  82. * @param string $key 
  83. * @param string $group Used to differentiate between groups of cache values 
  84. * @return array 
  85. */ 
  86. function get_with_old( $key, $group = '' ) { 
  87. $has_old_data = false; 
  88. $key = $this->get_item_key( $key ); 
  89. $path = $this->_cache_dir . '/' . $this->_get_path( $key ); 
  90.  
  91. $data = $this->_read( $path ); 
  92. if ( $data != null ) 
  93. return array( $data, $has_old_data ); 
  94.  
  95.  
  96. $path_old = $path . '_old'; 
  97. $too_old_time = time() - 30; 
  98.  
  99. if ( $exists = file_exists( $path_old ) ) { 
  100. $file_time = @filemtime( $path_old ); 
  101. if ( $file_time ) { 
  102. if ( $file_time > $too_old_time ) { 
  103. // return old data 
  104. $has_old_data = true; 
  105. return array( $this->_read( $path_old ), $has_old_data ); 
  106.  
  107.  
  108. // use old enough time to cause recalculation on next call 
  109. @touch( $path_old, 1479904835 ); 
  110. $has_old_data = $exists; 
  111.  
  112. return array( null, $has_old_data ); 
  113.  
  114. /** 
  115. * Reads file 
  116. * @param string $path 
  117. * @return array 
  118. */ 
  119. private function _read( $path ) { 
  120. if ( !is_readable( $path ) ) 
  121. return null; 
  122.  
  123. $fp = @fopen( $path, 'r' ); 
  124. if ( !$fp ) 
  125. return null; 
  126.  
  127. if ( $this->_locking ) 
  128. @flock( $fp, LOCK_SH ); 
  129.  
  130. $var = ''; 
  131.  
  132. while ( !@feof( $fp ) ) 
  133. $var .= @fread( $fp, 4096 ); 
  134.  
  135. @fclose( $fp ); 
  136.  
  137. if ( $this->_locking ) 
  138. @flock( $fp, LOCK_UN ); 
  139.  
  140. return array( 
  141. '404' => false,  
  142. 'headers' => array(),  
  143. 'time' => null,  
  144. 'content' => $var 
  145. ); 
  146.  
  147. /** 
  148. * Deletes data 
  149. * @param string $key 
  150. * @param string $group Used to differentiate between groups of cache values 
  151. * @return boolean 
  152. */ 
  153. function delete( $key, $group = '' ) { 
  154. $key = $this->get_item_key( $key ); 
  155. $path = $this->_cache_dir . DIRECTORY_SEPARATOR . $this->_get_path( $key ); 
  156.  
  157. if ( !file_exists( $path ) ) 
  158. return true; 
  159.  
  160. $old_entry_path = $path . '_old'; 
  161. if ( ! @rename( $path, $old_entry_path ) ) { 
  162. // if we can delete old entry - do second attempt to store in old-entry file 
  163. if ( ! @unlink( $old_entry_path ) || ! @rename( $path, $old_entry_path ) ) { 
  164. return @unlink( $path ); 
  165.  
  166. @touch( $old_entry_path, 1479904835 ); 
  167. return true; 
  168.  
  169. /** 
  170. * Key to delete, deletes _old and primary if exists. 
  171. * @param unknown $key 
  172. * @return bool 
  173. */ 
  174. function hard_delete( $key ) { 
  175. $key = $this->get_item_key( $key ); 
  176. $path = $this->_cache_dir . DIRECTORY_SEPARATOR . $this->_get_path( $key ); 
  177. $old_entry_path = $path . '_old'; 
  178. @unlink( $old_entry_path ); 
  179.  
  180. if ( !file_exists( $path ) ) 
  181. return true; 
  182. @unlink( $path ); 
  183. return true; 
  184.  
  185. /** 
  186. * Flushes all data 
  187. * @param string $group Used to differentiate between groups of cache values 
  188. * @return boolean 
  189. */ 
  190. function flush( $group = '' ) { 
  191. if ( $group == 'sitemaps' ) { 
  192. $config = Dispatcher::config(); 
  193. $sitemap_regex = $config->get_string( 'pgcache.purge.sitemap_regex' ); 
  194. $this->_flush_based_on_regex( $sitemap_regex ); 
  195. } else { 
  196. $c = new Cache_File_Cleaner_Generic( array( 
  197. 'cache_dir' => $this->_flush_dir,  
  198. 'exclude' => $this->_exclude,  
  199. 'clean_timelimit' => $this->_flush_timelimit 
  200. ) ); 
  201.  
  202. $c->clean(); 
  203.  
  204. /** 
  205. * Returns cache file path by key 
  206. * @param string $key 
  207. * @return string 
  208. */ 
  209. function _get_path( $key ) { 
  210. return $key; 
  211.  
  212. function get_item_key( $key ) { 
  213. return $key; 
  214.  
  215.  
  216. /** 
  217. * Flush cache based on regex 
  218. * @param string $regex 
  219. */ 
  220. private function _flush_based_on_regex( $regex ) { 
  221. if ( Util_Environment::is_wpmu() && !Util_Environment::is_wpmu_subdomain() ) { 
  222. $domain = get_home_url(); 
  223. $parsed = parse_url( $domain ); 
  224. $host = $parsed['host']; 
  225. $path = isset( $parsed['path'] ) ? '/' . trim( $parsed['path'], '/' ) : ''; 
  226. $flush_dir = W3TC_CACHE_PAGE_ENHANCED_DIR . '/' . $host . $path; 
  227. } else 
  228. $flush_dir = W3TC_CACHE_PAGE_ENHANCED_DIR . '/' . Util_Environment::host(); 
  229.  
  230. $dir = @opendir( $flush_dir ); 
  231. if ( $dir ) { 
  232. while ( ( $entry = @readdir( $dir ) ) !== false ) { 
  233. if ( $entry == '.' || $entry == '..' ) { 
  234. continue; 
  235. if ( preg_match( '~' . $regex . '~', basename( $entry ) ) ) { 
  236. Util_File::rmdir( $flush_dir . DIRECTORY_SEPARATOR . $entry ); 
  237.  
  238. @closedir( $dir );