Add wp_recache_rejected_cookies option (defaults: woocommerce_items_in_cart, wp_woocommerce_session_*, wp-postpass, comment_author_*, wordpress_*) that bypasses page cache when any listed cookie is present. Both the WP-level check (wp_recache_should_exclude) and the standalone drop-in apply the same exact/prefix matching logic. Editing the option regenerates the drop-in and purges all cache.
260 lines
5.8 KiB
PHP
260 lines
5.8 KiB
PHP
<?php
|
|
/**
|
|
* Common helper functions.
|
|
*
|
|
* @package WP_Recache
|
|
*/
|
|
|
|
defined('ABSPATH') || exit;
|
|
|
|
/**
|
|
* Check if cache is enabled.
|
|
*/
|
|
function wp_recache_is_cache_enabled() {
|
|
return (bool) get_option('wp_recache_cache_enabled', true);
|
|
}
|
|
|
|
/**
|
|
* Check if a specific feature is enabled.
|
|
*
|
|
* @param string $feature Feature name.
|
|
*/
|
|
function wp_recache_is_feature_enabled($feature) {
|
|
return (bool) get_option("wp_recache_{$feature}_enabled", false);
|
|
}
|
|
|
|
/**
|
|
* Get plugin option with default.
|
|
*
|
|
* @param string $option Option name.
|
|
* @param mixed $default Default value.
|
|
*/
|
|
function wp_recache_get_option($option, $default = false) {
|
|
return get_option("wp_recache_{$option}", $default);
|
|
}
|
|
|
|
/**
|
|
* Set plugin option.
|
|
*
|
|
* @param string $option Option name.
|
|
* @param mixed $value Option value.
|
|
*/
|
|
function wp_recache_set_option($option, $value) {
|
|
return update_option("wp_recache_{$option}", $value);
|
|
}
|
|
|
|
/**
|
|
* Check if current user is logged in.
|
|
*/
|
|
function wp_recache_is_logged_in() {
|
|
return is_user_logged_in();
|
|
}
|
|
|
|
/**
|
|
* Check if current request should be excluded from cache.
|
|
*/
|
|
function wp_recache_should_exclude() {
|
|
if (wp_recache_is_logged_in()) {
|
|
return true;
|
|
}
|
|
|
|
if (wp_recache_has_rejected_cookie()) {
|
|
return true;
|
|
}
|
|
|
|
// Dynamic query-string requests are never cached (story 11).
|
|
if (!empty($_SERVER['QUERY_STRING'])) {
|
|
return true;
|
|
}
|
|
|
|
if (is_preview() || is_feed() || is_404()) {
|
|
return true;
|
|
}
|
|
|
|
if (wp_recache_is_post_action()) {
|
|
return true;
|
|
}
|
|
|
|
$exclude_urls = wp_recache_get_option('exclude_urls', []);
|
|
$request_uri = wp_parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
|
|
|
|
foreach ($exclude_urls as $url) {
|
|
if (strpos($request_uri, trim($url)) !== false) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return apply_filters('wp_recache_exclude', false);
|
|
}
|
|
|
|
/**
|
|
* Check if a rejected cookie is present in the request.
|
|
*
|
|
* @return bool True if any rejected cookie is set.
|
|
*/
|
|
function wp_recache_has_rejected_cookie() {
|
|
if (empty($_COOKIE)) {
|
|
return false;
|
|
}
|
|
|
|
$rejected = wp_recache_get_option('rejected_cookies', [
|
|
'woocommerce_items_in_cart',
|
|
'wp_woocommerce_session_*',
|
|
'wp-postpass',
|
|
'comment_author_*',
|
|
'wordpress_*',
|
|
]);
|
|
|
|
foreach ($rejected as $cookie) {
|
|
$cookie = trim($cookie);
|
|
if ($cookie === '') {
|
|
continue;
|
|
}
|
|
|
|
if (substr($cookie, -1) === '*') {
|
|
$prefix = substr($cookie, 0, -1);
|
|
foreach ($_COOKIE as $name => $value) {
|
|
if (strpos($name, $prefix) === 0) {
|
|
return true;
|
|
}
|
|
}
|
|
} else {
|
|
if (isset($_COOKIE[$cookie])) {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Check if request is for a robot/crawler.
|
|
*/
|
|
function wp_recache_is_robots() {
|
|
return isset($_SERVER['HTTP_USER_AGENT']) && strpos($_SERVER['HTTP_USER_AGENT'], 'bot') !== false;
|
|
}
|
|
|
|
/**
|
|
* Check if request is a POST action.
|
|
*/
|
|
function wp_recache_is_post_action() {
|
|
return ($_SERVER['REQUEST_METHOD'] ?? 'GET') === 'POST';
|
|
}
|
|
|
|
/**
|
|
* Get cache file path for URL.
|
|
*
|
|
* Keyed by md5(host + path) so nested paths, hosts and multisite
|
|
* sub-directories never collide. Query strings are bypassed upstream.
|
|
*
|
|
* @param string $url URL to cache.
|
|
*/
|
|
function wp_recache_get_cache_path($url) {
|
|
$host = (string) wp_parse_url($url, PHP_URL_HOST);
|
|
$path = (string) wp_parse_url($url, PHP_URL_PATH);
|
|
|
|
return WP_RECACHE_CACHE_PATH . md5($host . $path) . '.html';
|
|
}
|
|
|
|
/**
|
|
* Delete cache file for URL.
|
|
*
|
|
* @param string $url URL to delete cache for.
|
|
*/
|
|
function wp_recache_delete_cache($url) {
|
|
$path = wp_recache_get_cache_path($url);
|
|
|
|
if (file_exists($path)) {
|
|
return unlink($path);
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Delete all cache files.
|
|
*/
|
|
function wp_recache_delete_all_cache() {
|
|
$cache_path = WP_RECACHE_CACHE_PATH;
|
|
|
|
if (!is_dir($cache_path)) {
|
|
return false;
|
|
}
|
|
|
|
$files = new RecursiveIteratorIterator(
|
|
new RecursiveDirectoryIterator($cache_path, RecursiveDirectoryIterator::SKIP_DOTS),
|
|
RecursiveIteratorIterator::CHILD_FIRST
|
|
);
|
|
|
|
foreach ($files as $file) {
|
|
if ($file->isDir()) {
|
|
rmdir($file->getRealPath());
|
|
} else {
|
|
unlink($file->getRealPath());
|
|
}
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
/**
|
|
* Check if URL is mobile.
|
|
*/
|
|
function wp_recache_is_mobile() {
|
|
if (!isset($_SERVER['HTTP_USER_AGENT'])) {
|
|
return false;
|
|
}
|
|
|
|
$mobile_agents = [
|
|
'android',
|
|
'iphone',
|
|
'ipad',
|
|
'ipod',
|
|
'blackberry',
|
|
'opera mini',
|
|
'opera mobi',
|
|
];
|
|
|
|
$user_agent = strtolower($_SERVER['HTTP_USER_AGENT']);
|
|
|
|
foreach ($mobile_agents as $agent) {
|
|
if (strpos($user_agent, $agent) !== false) {
|
|
return true;
|
|
}
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
/**
|
|
* Get cache file path for URL with mobile detection.
|
|
*
|
|
* @param string $url URL to cache.
|
|
*/
|
|
function wp_recache_get_cache_path_with_device($url) {
|
|
$path = wp_recache_get_cache_path($url);
|
|
|
|
if (wp_recache_get_option('separate_mobile_cache', false)) {
|
|
$device = wp_recache_is_mobile() ? 'mobile' : 'desktop';
|
|
$path = str_replace('.html', "-{$device}.html", $path);
|
|
}
|
|
|
|
return $path;
|
|
}
|
|
|
|
/**
|
|
* Enqueue the admin-bar purge script (admin and front-end admin bar).
|
|
*/
|
|
function wp_recache_enqueue_admin_bar_script() {
|
|
if (!is_admin_bar_showing() || !current_user_can('manage_options')) {
|
|
return;
|
|
}
|
|
|
|
wp_enqueue_script('wp-recache-admin', WP_RECACHE_URL . 'assets/admin.js', ['jquery'], WP_RECACHE_VERSION, true);
|
|
wp_localize_script('wp-recache-admin', 'wpRecache', [
|
|
'ajaxUrl' => admin_url('admin-ajax.php'),
|
|
'nonce' => wp_create_nonce('wp_recache_nonce'),
|
|
]);
|
|
}
|