You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
203 lines
6.1 KiB
203 lines
6.1 KiB
<?php |
|
class wfCache { |
|
private static $cacheStats = array(); |
|
private static $cacheClearedThisRequest = false; |
|
private static $lastRecursiveDeleteError = false; |
|
|
|
public static function removeCaching() { |
|
$cacheType = wfConfig::get('cacheType', false); |
|
if ($cacheType === 'disabled') { |
|
return; |
|
} |
|
|
|
if ($cacheType == 'falcon') { |
|
self::addHtaccessCode('remove'); |
|
self::updateBlockedIPs('remove'); |
|
} |
|
|
|
wfConfig::set('cacheType', 'disabled'); |
|
|
|
$cacheDir = WP_CONTENT_DIR . '/wfcache/'; |
|
if (file_exists($cacheDir . '.htaccess')) { |
|
unlink($cacheDir . '.htaccess'); |
|
} |
|
|
|
self::clearPageCacheSafe(); |
|
} |
|
public static function clearPageCacheSafe(){ |
|
if(self::$cacheClearedThisRequest){ return; } |
|
self::$cacheClearedThisRequest = true; |
|
self::clearPageCache(); |
|
} |
|
public static function clearPageCache(){ //If a clear is in progress this does nothing. |
|
self::$cacheStats = array( |
|
'dirsDeleted' => 0, |
|
'filesDeleted' => 0, |
|
'totalData' => 0, |
|
'totalErrors' => 0, |
|
'error' => '', |
|
); |
|
|
|
$cacheDir = WP_CONTENT_DIR . '/wfcache/'; |
|
if (!file_exists($cacheDir)) { |
|
return self::$cacheStats; |
|
} |
|
|
|
$cacheClearLock = WP_CONTENT_DIR . '/wfcache/clear.lock'; |
|
if(! is_file($cacheClearLock)){ |
|
if(! touch($cacheClearLock)){ |
|
self::$cacheStats['error'] = "Could not create a lock file $cacheClearLock to clear the cache."; |
|
self::$cacheStats['totalErrors']++; |
|
return self::$cacheStats; |
|
} |
|
} |
|
$fp = fopen($cacheClearLock, 'w'); |
|
if(! $fp){ |
|
self::$cacheStats['error'] = "Could not open the lock file $cacheClearLock to clear the cache. Please make sure the directory is writable by your web server."; |
|
self::$cacheStats['totalErrors']++; |
|
return self::$cacheStats; |
|
} |
|
if(flock($fp, LOCK_EX | LOCK_NB)){ //non blocking exclusive flock attempt. If we get a lock then it continues and returns true. If we don't lock, then return false, don't block and don't clear the cache. |
|
// This logic means that if a cache clear is currently in progress we don't try to clear the cache. |
|
// This prevents web server children from being queued up waiting to be able to also clear the cache. |
|
self::$lastRecursiveDeleteError = false; |
|
self::recursiveDelete(WP_CONTENT_DIR . '/wfcache/'); |
|
if(self::$lastRecursiveDeleteError){ |
|
self::$cacheStats['error'] = self::$lastRecursiveDeleteError; |
|
self::$cacheStats['totalErrors']++; |
|
} |
|
flock($fp, LOCK_UN); |
|
@unlink($cacheClearLock); |
|
@rmdir($cacheDir); |
|
} |
|
fclose($fp); |
|
|
|
return self::$cacheStats; |
|
} |
|
private static function recursiveDelete($dir) { |
|
$files = array_diff(scandir($dir), array('.','..')); |
|
foreach ($files as $file) { |
|
if(is_dir($dir . '/' . $file)){ |
|
if(! self::recursiveDelete($dir . '/' . $file)){ |
|
return false; |
|
} |
|
} else { |
|
if($file == 'clear.lock'){ continue; } //Don't delete our lock file |
|
$size = filesize($dir . '/' . $file); |
|
if($size){ |
|
self::$cacheStats['totalData'] += round($size / 1024); |
|
} |
|
if(strpos($dir, 'wfcache/') === false){ |
|
self::$lastRecursiveDeleteError = "Not deleting file in directory $dir because it appears to be in the wrong path."; |
|
self::$cacheStats['totalErrors']++; |
|
return false; //Safety check that we're in a subdir of the cache |
|
} |
|
if(@unlink($dir . '/' . $file)){ |
|
self::$cacheStats['filesDeleted']++; |
|
} else { |
|
self::$lastRecursiveDeleteError = "Could not delete file " . $dir . "/" . $file . " : " . wfUtils::getLastError(); |
|
self::$cacheStats['totalErrors']++; |
|
return false; |
|
} |
|
} |
|
} |
|
if($dir != WP_CONTENT_DIR . '/wfcache/'){ |
|
if(strpos($dir, 'wfcache/') === false){ |
|
self::$lastRecursiveDeleteError = "Not deleting directory $dir because it appears to be in the wrong path."; |
|
self::$cacheStats['totalErrors']++; |
|
return false; //Safety check that we're in a subdir of the cache |
|
} |
|
if(@rmdir($dir)){ |
|
self::$cacheStats['dirsDeleted']++; |
|
} else { |
|
self::$lastRecursiveDeleteError = "Could not delete directory $dir : " . wfUtils::getLastError(); |
|
self::$cacheStats['totalErrors']++; |
|
return false; |
|
} |
|
return true; |
|
} else { |
|
return true; |
|
} |
|
} |
|
public static function addHtaccessCode($action){ |
|
if($action != 'remove'){ |
|
die("Error: addHtaccessCode must be called with 'remove' as param"); |
|
} |
|
$htaccessPath = self::getHtaccessPath(); |
|
if(! $htaccessPath){ |
|
return "Wordfence could not find your .htaccess file."; |
|
} |
|
$fh = @fopen($htaccessPath, 'r+'); |
|
if(! $fh){ |
|
$err = error_get_last(); |
|
return $err['message']; |
|
} |
|
flock($fh, LOCK_EX); |
|
fseek($fh, 0, SEEK_SET); //start of file |
|
clearstatcache(); |
|
$contents = fread($fh, filesize($htaccessPath)); |
|
if(! $contents){ |
|
fclose($fh); |
|
return "Could not read from $htaccessPath"; |
|
} |
|
$contents = preg_replace('/#WFCACHECODE.*WFCACHECODE[\r\s\n\t]*/s', '', $contents); |
|
ftruncate($fh, 0); |
|
fflush($fh); |
|
fseek($fh, 0, SEEK_SET); |
|
fwrite($fh, $contents); |
|
flock($fh, LOCK_UN); |
|
fclose($fh); |
|
return false; |
|
} |
|
|
|
/** |
|
* @param $action |
|
* @return bool|string|void |
|
*/ |
|
public static function updateBlockedIPs($action){ //'add' or 'remove' |
|
$htaccessPath = self::getHtaccessPath(); |
|
if(! $htaccessPath){ |
|
return "Wordfence could not find your .htaccess file."; |
|
} |
|
if($action == 'remove'){ |
|
$fh = @fopen($htaccessPath, 'r+'); |
|
if(! $fh){ |
|
$err = error_get_last(); |
|
return $err['message']; |
|
} |
|
flock($fh, LOCK_EX); |
|
fseek($fh, 0, SEEK_SET); //start of file |
|
clearstatcache(); |
|
$contents = @fread($fh, filesize($htaccessPath)); |
|
if(! $contents){ |
|
fclose($fh); |
|
return "Could not read from $htaccessPath"; |
|
} |
|
|
|
$contents = preg_replace('/#WFIPBLOCKS.*WFIPBLOCKS[\r\s\n\t]*/s', '', $contents); |
|
|
|
ftruncate($fh, 0); |
|
fflush($fh); |
|
fseek($fh, 0, SEEK_SET); |
|
@fwrite($fh, $contents); |
|
flock($fh, LOCK_UN); |
|
fclose($fh); |
|
return false; |
|
} |
|
return false; |
|
} |
|
public static function getHtaccessPath(){ |
|
if (!function_exists('get_home_path')) { |
|
include_once(ABSPATH . 'wp-admin/includes/file.php'); |
|
} |
|
|
|
$homePath = get_home_path(); |
|
$htaccessFile = $homePath.'.htaccess'; |
|
return $htaccessFile; |
|
} |
|
public static function doNotCache(){ |
|
if(! defined('WFDONOTCACHE')){ |
|
define('WFDONOTCACHE', true); |
|
} |
|
} |
|
}
|
|
|