Commit 9c7db225 authored by Rolf Forst's avatar Rolf Forst
Browse files

Merge branch 'dev' into 'master'

Dev

See merge request !13
parents 9691195a 175c23b5
......@@ -3,10 +3,6 @@ if (!isset($_SERVER['REQUEST_METHOD']) || $_SERVER['REQUEST_METHOD'] != 'GET') {
return false;
}
if (!empty($_GET) && !isset($_GET['utm_source'], $_GET['utm_medium'], $_GET['utm_campaign'])) {
return false;
}
if (!empty($_COOKIE)) {
foreach ($_COOKIE as $k => $v) {
if (preg_match('/^(wp-postpass|wordpress_logged_in|comment_author)_/', $k)) {
......@@ -16,45 +12,34 @@ if (!empty($_COOKIE)) {
}
$timeout_file = WP_CONTENT_DIR . '/advanced-cache/timeout';
$expires_seconds = MINUTE_IN_SECONDS;
$expires_seconds = 10 * MINUTE_IN_SECONDS;
if (is_readable($timeout_file) && ($buffer = file_get_contents($timeout_file)) !== false) {
$expires_seconds = (int) $buffer * MINUTE_IN_SECONDS;
if (is_readable($timeout_file) && filesize($timeout_file) > 0) {
$expires_seconds = abs(intval(file_get_contents($timeout_file))) * MINUTE_IN_SECONDS;
}
$expires_seconds = $expires_seconds >= MINUTE_IN_SECONDS ? $expires_seconds : MINUTE_IN_SECONDS;
$expires_seconds = $expires_seconds >= (1 * MINUTE_IN_SECONDS) ? $expires_seconds : (10 * MINUTE_IN_SECONDS);
$path = sprintf(
'%s%s%s%s',
WP_CONTENT_DIR . '/advanced-cache',
DIRECTORY_SEPARATOR,
parse_url('https://' . strtolower($_SERVER['HTTP_HOST']), PHP_URL_HOST),
parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH)
);
$path = WP_CONTENT_DIR . '/advanced-cache' .
DIRECTORY_SEPARATOR .
parse_url('https://' . strtolower($_SERVER['HTTP_HOST']), PHP_URL_HOST) .
parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
$path = rtrim($path, '/\\') . '/';
$path_html = $path . 'index.html';
if (is_readable($path_html)
&& ($buffer = file_get_contents($path_html)) !== false
&& ((filemtime($path_html) + $expires_seconds) > time())) {
if (function_exists('apache_request_headers')) {
$headers = apache_request_headers();
$http_if_modified_since = isset($headers['If-Modified-Since']) ? $headers['If-Modified-Since'] : '';
$http_accept = isset($headers['Accept']) ? $headers['Accept'] : '';
$http_accept_encoding = isset($headers['Accept-Encoding']) ? $headers['Accept-Encoding'] : '';
} else {
$http_if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? $_SERVER['HTTP_IF_MODIFIED_SINCE'] : '';
$http_accept = isset($_SERVER['HTTP_ACCEPT']) ? $_SERVER['HTTP_ACCEPT'] : '';
$http_accept_encoding = isset($_SERVER['HTTP_ACCEPT_ENCODING']) ? $_SERVER['HTTP_ACCEPT_ENCODING'] : '';
}
$cache_file = $path . 'index.html';
if ($http_if_modified_since && strtotime($http_if_modified_since) == filemtime($path_html)) {
header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified', true, 304);
// Check if the cache file exists and is readable.
if (is_readable($cache_file) && ($content = file_get_contents($cache_file)) !== false && (filesize($cache_file) > 0)) {
// Check if the cache file is not stale.
if (($filemtime = filemtime($cache_file) + $expires_seconds) > time()) {
// Not stale: Output the content of the cache file.
header('Last-Modified: ' . date('r', $filemtime), true);
header('Cache-Control: max-age=' . $expires_seconds . ', must-revalidate', true);
echo $content;
exit;
} else {
// Stale: Remove the cache file.
unlink($cache_file);
}
echo $buffer;
exit;
}
......@@ -6,35 +6,132 @@ defined('ABSPATH') || exit;
final class File
{
/**
* [protected description]
* @var string
*/
protected static $cacheFile = WP_CONTENT_DIR . '/advanced-cache.php';
/**
* [protected description]
* @var string
*/
protected static $cacheDir = WP_CONTENT_DIR . '/advanced-cache';
/**
* [protected description]
* @var string
*/
protected static $cacheOldDir = WP_CONTENT_DIR . '/advanced-cache-old';
/**
* [protected description]
* @var string
*/
protected static $timeoutFile = WP_CONTENT_DIR . '/advanced-cache/timeout';
/**
* [createSymlink description]
* @return boolean [description]
*/
public static function createSymlink()
{
if (!file_exists(self::$cacheFile)) {
$rrzeCacheFile = plugin()->getPath() . 'advanced-cache.php';
if (function_exists('symlink')) {
return symlink($rrzeCacheFile, self::$cacheFile);
}
return false;
}
return true;
}
/**
* [removeSymlink description]
* @return boolean [description]
*/
public static function removeSymlink(): bool
{
return @unlink(self::$cacheFile);
}
/**
* [createCacheDir description]
* @return boolean [description]
*/
public static function createCacheDir(): bool
{
if (file_exists(self::$cacheDir)) {
return true;
}
if (!wp_mkdir_p(self::$cacheDir)) {
do_action('rrze.log.error', __('{plugin}: The directory could not be created.', 'rrze-cache'), ['plugin' => 'rrze-cache', 'method' => __METHOD__, 'File::$cacheDir' => self::$cacheDir]);
return false;
}
return true;
}
/**
* [createCacheOldDir description]
* @return boolean [description]
*/
public static function createCacheOldDir(): bool
{
if (file_exists(self::$cacheOldDir)) {
return true;
}
if (!wp_mkdir_p(self::$cacheOldDir)) {
do_action('rrze.log.error', __('{plugin}: The directory could not be created.', 'rrze-cache'), ['plugin' => 'rrze-cache', 'method' => __METHOD__, 'File::$cacheOldDir' => self::$cacheOldDir]);
return false;
}
return true;
}
/**
* [storeTimeout description]
* @param integer $cacheExpires [description]
* @return boolean [description]
*/
public static function storeTimeout($cacheExpires = 0)
public static function storeTimeout(int $cacheExpires = 10): bool
{
$cacheExpires = absint($cacheExpires) ? absint($cacheExpires) : 1;
self::createTimeoutFile($cacheExpires);
$cacheExpires = absint($cacheExpires) ? absint($cacheExpires) : 10;
return self::createTimeoutFile($cacheExpires);
}
/**
* [createTimeoutFile description]
* @param integer $cacheExpires [description]
* @return boolean [description]
*/
protected static function createTimeoutFile(int $cacheExpires): bool
{
if (!$handle = @fopen(self::$timeoutFile, 'wb')) {
do_action('rrze.log.error', __('{plugin}: The timeout cache file could not be written.', 'rrze-cache'), ['plugin' => 'rrze-cache', 'method' => __METHOD__, '$timeoutFile' => self::$timeoutFile]);
return false;
}
fwrite($handle, $cacheExpires);
fclose($handle);
clearstatcache();
self::fileChmod(self::$timeoutFile);
return true;
}
/**
* [storeItem description]
* @param string $data [description]
* @return [type] [description]
* @return boolean [description]
*/
public static function storeItem($data = '')
public static function storeItem(string $data = ''): bool
{
if (empty($data)) {
do_action('rrze.log.error', __('{plugin}: Can not save cache item. The data is empty.', 'rrze-cache'), ['plugin' =>'rrze-cache', 'method' => __METHOD__]);
do_action('rrze.log.error', __('{plugin}: Can not save cache item. The data is empty.', 'rrze-cache'), ['plugin' => 'rrze-cache', 'method' => __METHOD__]);
return false;
}
self::createFiles($data . self::cacheSignatur());
return self::createFiles($data . self::cacheSignatur());
}
/**
......@@ -42,53 +139,52 @@ final class File
* @param integer $cacheExpires [description]
* @return boolean [description]
*/
public static function getItem($cacheExpires = 0)
public static function getItem(int $cacheExpires = 0): bool
{
$cacheExpires = absint($cacheExpires) ? absint($cacheExpires) : 1;
$expires_seconds = $cacheExpires * MINUTE_IN_SECONDS;
if (is_readable(self::fileHtml()) && ((filemtime(self::fileHtml()) + $expires_seconds) > time())) {
return true;
}
return false;
}
/**
* [deleteItem description]
* @param string $url [description]
* @return mixed [description]
* @return boolean [description]
*/
public static function deleteItem($url = '')
public static function deleteItem(string $url = ''): bool
{
if (! filter_var($url, FILTER_VALIDATE_URL)) {
do_action('rrze.log.error', __('{pluginn}: The URL is not valid.'), ['plugin' =>'rrze-cache', 'method' => __METHOD__]);
if (!filter_var($url, FILTER_VALIDATE_URL)) {
do_action('rrze.log.error', __('{pluginn}: The URL is not valid.'), ['plugin' => 'rrze-cache', 'method' => __METHOD__]);
return false;
}
$url_path = parse_url(($url ? $url : $_SERVER['REQUEST_URI']), PHP_URL_PATH);
$recursive = untrailingslashit($url_path) ? true : false;
self::clearDir(self::filePath($url), $recursive);
$url_path = untrailingslashit(parse_url(($url ? $url : $_SERVER['REQUEST_URI']), PHP_URL_PATH));
return self::removeDir(self::filePath($url_path), false);
}
/**
* [clearData description]
* @param boolean $clearAll [description]
* @param boolean $all [description]
* @return boolean [description]
*/
public static function clearData($clearAll = false)
public static function clearData($all = false): bool
{
if ($clearAll === false) {
self::clearDir(self::dirPath());
} else {
self::clearDir(self::$cacheDir);
}
}
$sourceDir = $all ? self::$cacheDir : self::dirPath();
$targetDir = self::$cacheOldDir .
DIRECTORY_SEPARATOR .
bin2hex(random_bytes(8));
return self::renameDir($sourceDir, $targetDir);
}
/**
* [cacheSignatur description]
* @return string [description]
*/
protected static function cacheSignatur()
protected static function cacheSignatur(): string
{
return sprintf("\n\n<!-- %s -->", date_i18n(__('Y-m-d H:i:s', 'rrze-cache'), current_time('timestamp')));
}
......@@ -98,11 +194,11 @@ final class File
* @param string $data [description]
* @return boolean
*/
protected static function createFiles($data)
protected static function createFiles(string $data): bool
{
$filePath = self::filePath();
if (! wp_mkdir_p($filePath)) {
do_action('rrze.log.error', __('{plugin}: The directory could not be created.', 'rrze-cache'), ['plugin' =>'rrze-cache', 'method' => __METHOD__, '$filePath' => $filePath]);
if (!wp_mkdir_p($filePath)) {
do_action('rrze.log.error', __('{plugin}: The directory could not be created.', 'rrze-cache'), ['plugin' => 'rrze-cache', 'method' => __METHOD__, '$filePath' => $filePath]);
return false;
}
......@@ -110,49 +206,16 @@ final class File
return true;
}
/**
* [createTimeoutFile description]
* @param integer $cacheExpires [description]
* @return boolean [description]
*/
protected static function createTimeoutFile($cacheExpires)
{
if (! wp_mkdir_p(self::$cacheDir)) {
do_action('rrze.log.error', __('{plugin}: The directory could not be created.', 'rrze-cache'), ['plugin' =>'rrze-cache', 'method' => __METHOD__, 'File::$cacheDir' => self::$cacheDir]);
return false;
}
$file = sprintf(
'%s%s%s',
self::$cacheDir,
DIRECTORY_SEPARATOR,
'timeout'
);
if (! $handle = @fopen($file, 'wb')) {
do_action('rrze.log.error', __('{plugin}: The timeout cache file could not be written.', 'rrze-cache'), ['plugin' =>'rrze-cache', 'method' => __METHOD__, '$file' => $file]);
return false;
}
fwrite($handle, $cacheExpires);
fclose($handle);
clearstatcache();
self::fileChmod($file);
return true;
}
/**
* [writeFile description]
* @param string $file [description]
* @param string $data [description]
* @return boolean [description]
*/
protected static function writeFile($file, $data)
protected static function writeFile(string $file, string $data): bool
{
if (! $handle = @fopen($file, 'wb')) {
do_action('rrze.log.error', __('{plugin}: The cache file could not be written.', 'rrze-cache'), ['plugin' =>'rrze-cache', 'method' => __METHOD__, '$file' => $file]);
if (!$handle = @fopen($file, 'wb')) {
do_action('rrze.log.error', __('{plugin}: The cache file could not be written.', 'rrze-cache'), ['plugin' => 'rrze-cache', 'method' => __METHOD__, '$file' => $file]);
return false;
}
......@@ -160,57 +223,22 @@ final class File
fclose($handle);
clearstatcache();
self::fileChmod($file);
return true;
return self::fileChmod($file);
}
/**
* [fileChmod description]
* @param string $file [description]
* @return boolean [description]
*/
protected static function fileChmod($file)
protected static function fileChmod(string $file): bool
{
$stat = @stat(dirname($file));
$perms = $stat['mode'] & 0007777;
$perms = $perms & 0000666;
@chmod($file, $perms);
clearstatcache();
}
/**
* [clearDir description]
* @param string $dir [description]
* @param boolean $recursive [description]
* @return void
*/
protected static function clearDir($dir, $recursive = true)
{
$dir = untrailingslashit($dir);
if (! is_dir($dir)) {
return;
}
$filenames = array_diff(scandir($dir), ['..', '.']);
if (empty($filenames)) {
return;
}
foreach ($filenames as $filename) {
$filename = $dir . DIRECTORY_SEPARATOR . $filename;
if (is_dir($filename) && $recursive) {
self::clearDir($filename, $recursive);
} else {
unlink($filename);
}
}
@rmdir($dir);
$return = @chmod($file, $perms);
clearstatcache();
return $return;
}
/**
......@@ -219,19 +247,16 @@ final class File
*/
protected static function dirPath()
{
$path = sprintf(
'%s%s%s',
self::$cacheDir,
DIRECTORY_SEPARATOR,
parse_url('http://' . strtolower($_SERVER['HTTP_HOST']), PHP_URL_HOST)
);
$path = self::$cacheDir .
DIRECTORY_SEPARATOR .
parse_url('http://' . strtolower($_SERVER['HTTP_HOST']), PHP_URL_HOST);
if (validate_file($path) > 0) {
do_action('rrze.log.error', __('{plugin}: Invalid file path.'), ['plugin' =>'rrze-cache', 'method' => __METHOD__, '$path' => $path]);
do_action('rrze.log.error', __('{plugin}: Invalid file path.'), ['plugin' => 'rrze-cache', 'method' => __METHOD__, '$path' => $path]);
return false;
}
return trailingslashit($path);
return $path;
}
/**
......@@ -239,18 +264,15 @@ final class File
* @param string $path [description]
* @return mixed [description]
*/
protected static function filePath($path = '')
protected static function filePath(string $path = '')
{
$path = sprintf(
'%s%s%s%s',
self::$cacheDir,
DIRECTORY_SEPARATOR,
parse_url('http://' . strtolower($_SERVER['HTTP_HOST']), PHP_URL_HOST),
parse_url(($path ? $path : $_SERVER['REQUEST_URI']), PHP_URL_PATH)
);
$path = self::$cacheDir .
DIRECTORY_SEPARATOR .
parse_url('http://' . strtolower($_SERVER['HTTP_HOST']), PHP_URL_HOST) .
parse_url(($path ? $path : $_SERVER['REQUEST_URI']), PHP_URL_PATH);
if (validate_file($path) > 0) {
do_action('rrze.log.error', __('{plugin}: Invalid file path.', 'rrze-cache'), ['plugin' =>'rrze-cache', 'method' => __METHOD__, '$path' => $path]);
do_action('rrze.log.error', __('{plugin}: Invalid file path.', 'rrze-cache'), ['plugin' => 'rrze-cache', 'method' => __METHOD__, '$path' => $path]);
return false;
}
......@@ -261,9 +283,91 @@ final class File
* [fileHtml description]
* @return string [description]
*/
protected static function fileHtml()
protected static function fileHtml(): string
{
return self::filePath() . 'index.html';
}
/**
* Rename a directory.
* @param string $source The source directory path.
* @param string $target The target directory path.
* @return bool TRUE on success, otherwise FALSE.
*/
protected static function renameDir(string $source, string $target): bool
{
$result = false;
// Handle arguments.
if (empty($source) || !file_exists($source)) {
return true; // No such file/folder exists.
} elseif (@is_file($source) || @is_link($source)) {
$result = true; // Rename file/link.
} elseif (@is_dir($source)) {
$result = true; // Rename directory.
}
clearstatcache();
return ($result ? rename($source, $target) : false);
}
/**
* Recursively deletes a directory tree.
* @param string $folder The directory path.
* @param bool $keepRootFolder Whether to keep the top-level folder.
* @return bool TRUE on success, otherwise FALSE.
*/
protected static function removeDir(string $folder, bool $keepRootFolder = false): bool
{
// Handle arguments.
if (empty($folder) || !file_exists($folder)) {
return true; // No such file/folder exists.
} elseif (is_file($folder) || is_link($folder)) {
return @unlink($folder); // Delete file/link.
}
// Get all children.
$files = new \RecursiveIteratorIterator(
new \RecursiveDirectoryIterator($folder, \RecursiveDirectoryIterator::SKIP_DOTS),
\RecursiveIteratorIterator::CHILD_FIRST
);
// Delete all children.
foreach ($files as $fileinfo) {
$action = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
if (!@$action($fileinfo->getRealPath())) {
return false; // Abort due to the failure.
}
}
clearstatcache();
return (!$keepRootFolder ? @rmdir($folder) : true);
}
/**
* [getCacheFile description]
* @return string [description]
*/
public static function getCacheFile(): string
{
return self::$cacheFile;
}
/**
* [getCacheDir description]
* @return string [description]
*/
public static function getCacheDir(): string
{
return self::$cacheDir;
}
/**
* [getTimeoutFile description]
* @return string [description]
*/
public static function getTimeoutFile(): string
{
return self::$timeoutFile;
}
}
......@@ -4,49 +4,47 @@ namespace RRZE\Cache;
defined('ABSPATH') || exit;
class Flush {
class Flush
{
/**
* [flushCacheByPostId description]
* @param integer $postId [description]
* @return boolean [description]
*/
public static function flushCacheByPostId($postId)
public static function flushCacheByPostId(int $postId): bool
{
if (! $postId = absint($postId)) {
return;
if (($permalink = get_permalink($postId)) === false) {
return false;
}
self::flushCacheByUrl(get_permalink($postId));
return self::flushCacheByUrl($permalink);
}
/**
* [flushCacheByUrl description]
* @param string $url [description]
* @return void
* @return boolean [description]
*/
public static function flushCacheByUrl($url)
public static function flushCacheByUrl(string $url): bool
{
if (! $url = (string) $url) {
return;
}
File::deleteItem($url);
return File::deleteItem($url);
}
/**
* [flushCache description]
* @return boolean [description]
*/
public static function flushCache()
public static function flushCache(): bool
{
File::clearData();
return File::clearData();
}
/**
* [flushAllCache description]
* @return boolean [description]
*/
public static function flushAllCache()
public static function flushAllCache(): bool