This commit is contained in:
2026-07-02 15:54:39 -06:00
commit 9883323161
17470 changed files with 4470592 additions and 0 deletions
@@ -0,0 +1,75 @@
<?php //Pressable Cache Purge Adds a Cache Purge button to the admin bar
// disable direct file access
if (!defined('ABSPATH'))
{
exit;
}
add_action( 'admin_bar_menu', 'cache_add_item', 100 );
function cache_add_item( $admin_bar ) {
if ( is_admin() ) {
global $pagenow;
$admin_bar->add_menu(
array(
'id' => 'cache-purge',
'title' => 'Object Cache Purge',
'href' => '#',
)
);
// $admin_bar->add_menu( array( 'id'=>'settings','title'=>'Cache Settings', 'parent'=> 'cache-purge', 'href'=>'admin.php?page=pressable_cache_management' ) );
}
}
add_action( 'admin_footer', 'cache_purge_action_js' );
function cache_purge_action_js() { ?>
<script type="text/javascript" >
jQuery("li#wp-admin-bar-cache-purge .ab-item").on( "click", function() {
var data = {
'action': 'pressable_cache_purge',
};
jQuery.post(ajaxurl, data, function(response) {
alert( response );
});
});
</script>
<style type="text/css">
/*#wp-admin-bar-cache-purge .ab-item {
background-color: #0AD8C7;
}
*/
</style>
<?php
}
add_action( 'wp_ajax_pressable_cache_purge', 'pressable_cache_purge_callback' );
function pressable_cache_purge_callback() {
wp_cache_flush();
//Save time stamp to database if cache is flushed.
$object_cache_flush_time = date( ' jS F Y g:ia' ) . "\nUTC";
update_option( 'flush-obj-cache-time-stamp', $object_cache_flush_time );
$response = 'Object Cache Purged';
echo $response;
wp_die();
}
@@ -0,0 +1,117 @@
<?php // Pressable Cache Management - Enable Caching for pages which has wpp_ cookies
// disable direct file access
if (!defined('ABSPATH'))
{
exit;
}
$options = get_option('pressable_cache_management_options');
if (isset($options['cache_wpp_cookies_pages']) && !empty($options['cache_wpp_cookies_pages']))
{
//Create the pressable-cache-management mu-plugin index file
$pcm_mu_plugins_index = WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management.php';
if (!file_exists($pcm_mu_plugins_index))
{
// Copy pressable-cache-management.php from plugin directory to mu-plugins directory
copy(plugin_dir_path(__FILE__) . '/pressable_cache_management_mu_plugin_index.php', $pcm_mu_plugins_index);
}
// Check if the pressable-cache-management directory exists or create the folder
if (!file_exists(WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/'))
{
//create the directory
wp_mkdir_p(WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/');
}
//Add the option from the textbox into the database
update_option('cache_wpp_cookies_pages', $options['cache_wpp_cookies_pages']);
$obj_cache_wpp_cookies_pages = WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/pcm_cache_wpp_cookies_pages.php';
if (file_exists($obj_cache_wpp_cookies_pages))
{
}
else
{
$obj_cache_wpp_cookies_pages = plugin_dir_path(__FILE__) . '/cache_wpp_cookie_page_mu_plugin.php';
$obj_cache_wpp_cookies_pages_active = WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/pcm_cache_wpp_cookies_pages.php';
//Flush cache to enable activation take effect immediately
wp_cache_flush();
if (!copy($obj_cache_wpp_cookies_pages, $obj_cache_wpp_cookies_pages_active))
{
}
else
{
}
}
//Display admin notice
function cache_wpp_cookies_pages_admin_notice($message = '', $classes = 'notice-success')
{
if (!empty($message))
{
printf('<div class="notice %2$s">%1$s</div>', $message, $classes);
}
}
function pcm_cache_wpp_cookies_pages_admin_notice()
{
$cache_wpp_cookies_pages_activate_display_notice = get_option('cache_wpp_cookies_pages_activate_notice', 'activating');
if ('activating' === $cache_wpp_cookies_pages_activate_display_notice && current_user_can('manage_options'))
{
add_action('admin_notices', function ()
{
$screen = get_current_screen();
//Display admin notice for this plugin page only
if ($screen->id !== 'toplevel_page_pressable_cache_management') return;
$user = $GLOBALS['current_user'];
$message = sprintf('<p>Batcache will now cache pages with wpp_ cookies.</p>');
cache_wpp_cookies_pages_admin_notice($message, 'notice notice-success is-dismissible');
});
update_option('cache_wpp_cookies_pages_activate_notice', 'activated');
}
}
add_action('init', 'pcm_cache_wpp_cookies_pages_admin_notice');
}
else
{
/**Update option from the database if the option is deactivated
used by admin notice to display and remove notice**/
update_option('cache_wpp_cookies_pages_activate_notice', 'activating');
$obj_cache_wpp_cookies_pages = WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/pcm_cache_wpp_cookies_pages.php';
if (file_exists($obj_cache_wpp_cookies_pages))
{
unlink($obj_cache_wpp_cookies_pages);
//Flush cache to enable deactivation take effect immediately
wp_cache_flush();
}
else
{
// File not found.
}
}
@@ -0,0 +1,35 @@
<?php // Pressable Cache Management - Cache pages which sets wpp_ cookies
// disable direct file access
if (!defined('ABSPATH'))
{
exit;
}
/**
* Batcache by default ignore all cookies starting with wp so
* we have to add cookies to skip list if we want batcache to
* cache certain pages with cookies.
*
* Wonder plugin sets cookies starting with wpp which was preventing pages
* getting cached. We collect all the cookies starting with wpp_ below
* and adds it to the list that can be cached
*/
$all_wpp_cookies = array();
if ( is_array( $_COOKIE) && ! empty( $_COOKIE ) ) {
foreach ( array_keys( $_COOKIE ) as $maybe_wpp ) {
if ( substr( $maybe_wpp, 0, 4 ) == 'wpp_' ) {
$all_wpp_cookies[] = $maybe_wpp;
}
}
}
// Only add cookies to noskip if we found any starting with wpp_
// The wordpress_test_cookies is the default one
if( count($all_wpp_cookies) > 0 ){
global $batcache;
$batcache['noskip_cookies'] = array_merge( array('wordpress_test_cookie'), $all_wpp_cookies );
}
@@ -0,0 +1,229 @@
<?php
/**
* Pressable Cache Management - Edge Cache Defensive Mode
*
* Mirrors the exact pattern used in edge_cache_admin_action_handler():
* query_ec_backend( $endpoint, array( 'body' => $data ) )
*
* Enable: POST to ddos_until with body timestamp = time() + duration_seconds
* Disable: POST to ddos_until with body timestamp = 0
* Status: get_ec_ddos_until() — returns the Unix timestamp or 0 if off
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// ─── Duration map: slug => [ label, seconds ] ────────────────────────────────
function pcm_defensive_mode_durations() {
return [
'30-minutes' => [ 'label' => '30 minutes', 'seconds' => 30 * MINUTE_IN_SECONDS ],
'45-minutes' => [ 'label' => '45 minutes', 'seconds' => 45 * MINUTE_IN_SECONDS ],
'1-hour' => [ 'label' => '1 hour', 'seconds' => HOUR_IN_SECONDS ],
'2-hours' => [ 'label' => '2 hours', 'seconds' => 2 * HOUR_IN_SECONDS ],
'3-hours' => [ 'label' => '3 hours', 'seconds' => 3 * HOUR_IN_SECONDS ],
'4-hours' => [ 'label' => '4 hours', 'seconds' => 4 * HOUR_IN_SECONDS ],
'5-hours' => [ 'label' => '5 hours', 'seconds' => 5 * HOUR_IN_SECONDS ],
'6-hours' => [ 'label' => '6 hours', 'seconds' => 6 * HOUR_IN_SECONDS ],
'7-hours' => [ 'label' => '7 hours', 'seconds' => 7 * HOUR_IN_SECONDS ],
'8-hours' => [ 'label' => '8 hours', 'seconds' => 8 * HOUR_IN_SECONDS ],
'9-hours' => [ 'label' => '9 hours', 'seconds' => 9 * HOUR_IN_SECONDS ],
'10-hours' => [ 'label' => '10 hours', 'seconds' => 10 * HOUR_IN_SECONDS ],
'11-hours' => [ 'label' => '11 hours', 'seconds' => 11 * HOUR_IN_SECONDS ],
'12-hours' => [ 'label' => '12 hours', 'seconds' => 12 * HOUR_IN_SECONDS ],
'13-hours' => [ 'label' => '13 hours', 'seconds' => 13 * HOUR_IN_SECONDS ],
'14-hours' => [ 'label' => '14 hours', 'seconds' => 14 * HOUR_IN_SECONDS ],
'15-hours' => [ 'label' => '15 hours', 'seconds' => 15 * HOUR_IN_SECONDS ],
'16-hours' => [ 'label' => '16 hours', 'seconds' => 16 * HOUR_IN_SECONDS ],
'17-hours' => [ 'label' => '17 hours', 'seconds' => 17 * HOUR_IN_SECONDS ],
'18-hours' => [ 'label' => '18 hours', 'seconds' => 18 * HOUR_IN_SECONDS ],
'19-hours' => [ 'label' => '19 hours', 'seconds' => 19 * HOUR_IN_SECONDS ],
'20-hours' => [ 'label' => '20 hours', 'seconds' => 20 * HOUR_IN_SECONDS ],
'21-hours' => [ 'label' => '21 hours', 'seconds' => 21 * HOUR_IN_SECONDS ],
'22-hours' => [ 'label' => '22 hours', 'seconds' => 22 * HOUR_IN_SECONDS ],
'23-hours' => [ 'label' => '23 hours', 'seconds' => 23 * HOUR_IN_SECONDS ],
'1-day' => [ 'label' => '1 day', 'seconds' => DAY_IN_SECONDS ],
'2-days' => [ 'label' => '2 days', 'seconds' => 2 * DAY_IN_SECONDS ],
'3-days' => [ 'label' => '3 days', 'seconds' => 3 * DAY_IN_SECONDS ],
'4-days' => [ 'label' => '4 days', 'seconds' => 4 * DAY_IN_SECONDS ],
'5-days' => [ 'label' => '5 days', 'seconds' => 5 * DAY_IN_SECONDS ],
'6-days' => [ 'label' => '6 days', 'seconds' => 6 * DAY_IN_SECONDS ],
'7-days' => [ 'label' => '7 days', 'seconds' => 7 * DAY_IN_SECONDS ],
];
}
// ─── Enable Defensive Mode ────────────────────────────────────────────────────
function pcm_pressable_enable_defensive_mode() {
if ( ! isset( $_POST['enable_defensive_mode_nonce'] ) ) {
return;
}
if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['enable_defensive_mode_nonce'] ) ), 'enable_defensive_mode_nonce' ) ) {
return;
}
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
$durations = pcm_defensive_mode_durations();
$slug = isset( $_POST['defensive_mode_duration'] )
? sanitize_text_field( wp_unslash( $_POST['defensive_mode_duration'] ) )
: '30-minutes';
if ( ! array_key_exists( $slug, $durations ) ) {
$slug = '30-minutes';
}
if ( ! class_exists( 'Edge_Cache_Plugin' ) ) {
add_action( 'admin_notices', function() {
if ( function_exists( 'pcm_branded_notice' ) ) {
pcm_branded_notice( esc_html__( 'Error: Edge Cache Plugin is not active.', 'pressable_cache_management' ), '#dd3a03' );
}
} );
return;
}
$expires_at = time() + $durations[ $slug ]['seconds'];
$edge_cache = Edge_Cache_Plugin::get_instance();
$result = $edge_cache->query_ec_backend( 'ddos_until', array(
'body' => array(
'timestamp' => $expires_at,
'wp_action' => 'manual_dashboard_set',
),
) );
if ( false === $result['success'] ) {
$err = ! empty( $result['error'] ) ? $result['error'] : esc_html__( 'Unknown error enabling Defensive Mode.', 'pressable_cache_management' );
add_action( 'admin_notices', function() use ( $err ) {
if ( function_exists( 'pcm_branded_notice' ) ) {
pcm_branded_notice( $err, '#dd3a03' );
}
} );
} else {
update_option( 'edge-cache-defensive-mode-active', 'yes' );
update_option( 'edge-cache-defensive-mode-slug', $slug );
update_option( 'edge-cache-defensive-mode-expires-at', $expires_at );
update_option( 'edge-cache-defensive-mode-set-at', gmdate( 'j M Y, g:ia' ) . ' UTC' );
delete_transient( 'pcm_ec_status_cache' );
do_action( 'pcm_after_defensive_mode_change' );
$label = $durations[ $slug ]['label'];
add_action( 'admin_notices', function() use ( $label ) {
if ( function_exists( 'pcm_branded_notice' ) ) {
pcm_branded_notice(
sprintf( esc_html__( 'Defensive Mode enabled for %s.', 'pressable_cache_management' ), $label ),
'#03fcc2'
);
}
} );
}
}
add_action( 'init', 'pcm_pressable_enable_defensive_mode' );
// ─── Disable Defensive Mode ───────────────────────────────────────────────────
function pcm_pressable_disable_defensive_mode() {
if ( ! isset( $_POST['disable_defensive_mode_nonce'] ) ) {
return;
}
if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['disable_defensive_mode_nonce'] ) ), 'disable_defensive_mode_nonce' ) ) {
return;
}
if ( ! current_user_can( 'manage_options' ) ) {
return;
}
if ( ! class_exists( 'Edge_Cache_Plugin' ) ) {
add_action( 'admin_notices', function() {
if ( function_exists( 'pcm_branded_notice' ) ) {
pcm_branded_notice( esc_html__( 'Error: Edge Cache Plugin is not active.', 'pressable_cache_management' ), '#dd3a03' );
}
} );
return;
}
$edge_cache = Edge_Cache_Plugin::get_instance();
$result = $edge_cache->query_ec_backend( 'ddos_until', array(
'body' => array(
'timestamp' => 0,
'wp_action' => 'manual_dashboard_set',
),
) );
if ( false === $result['success'] ) {
$err = ! empty( $result['error'] ) ? $result['error'] : esc_html__( 'Unknown error disabling Defensive Mode.', 'pressable_cache_management' );
add_action( 'admin_notices', function() use ( $err ) {
if ( function_exists( 'pcm_branded_notice' ) ) {
pcm_branded_notice( $err, '#dd3a03' );
}
} );
} else {
update_option( 'edge-cache-defensive-mode-active', 'no' );
update_option( 'edge-cache-defensive-mode-slug', '' );
update_option( 'edge-cache-defensive-mode-expires-at', 0 );
update_option( 'edge-cache-defensive-mode-set-at', '' );
delete_transient( 'pcm_ec_status_cache' );
do_action( 'pcm_after_defensive_mode_change' );
add_action( 'admin_notices', function() {
if ( function_exists( 'pcm_branded_notice' ) ) {
pcm_branded_notice( esc_html__( 'Defensive Mode disabled.', 'pressable_cache_management' ), '#03fcc2' );
}
} );
}
}
add_action( 'init', 'pcm_pressable_disable_defensive_mode' );
// ─── AJAX: check defensive mode status from server ───────────────────────────
// Uses get_ec_ddos_until() which calls query_ec_backend( 'ddos_until' ) as a
// GET (no body args) and returns the ddos_until Unix timestamp, or 0 if off.
function pcm_ajax_check_defensive_mode_status() {
if ( ! current_user_can( 'manage_options' ) ) {
wp_send_json_error( [ 'message' => 'Unauthorized' ], 403 );
return;
}
if ( ! class_exists( 'Edge_Cache_Plugin' ) ) {
wp_send_json_error( [ 'message' => 'Edge Cache Plugin not available.' ] );
return;
}
$edge_cache = Edge_Cache_Plugin::get_instance();
$ddos_until = $edge_cache->get_ec_ddos_until(); // returns int timestamp or EC_ERROR (-1)
// EC_ERROR means the API call failed
if ( Edge_Cache_Plugin::EC_ERROR === $ddos_until ) {
wp_send_json_error( [ 'message' => 'Could not retrieve Defensive Mode status from server.' ] );
return;
}
$is_defensive = $ddos_until > time();
if ( $is_defensive ) {
// Sync local flag if mode was activated externally (WP-CLI, direct API)
update_option( 'edge-cache-defensive-mode-active', 'yes' );
update_option( 'edge-cache-defensive-mode-expires-at', $ddos_until );
$set_at = get_option( 'edge-cache-defensive-mode-set-at', '' );
$expires_str = gmdate( 'j M Y, g:ia', $ddos_until ) . ' UTC';
wp_send_json_success( [
'defensive_active' => true,
'set_at' => $set_at,
'expires_at' => $expires_str,
] );
} else {
// Server says off — sync local options
update_option( 'edge-cache-defensive-mode-active', 'no' );
update_option( 'edge-cache-defensive-mode-slug', '' );
update_option( 'edge-cache-defensive-mode-expires-at', 0 );
update_option( 'edge-cache-defensive-mode-set-at', '' );
wp_send_json_success( [
'defensive_active' => false,
'set_at' => '',
'expires_at' => '',
] );
}
}
add_action( 'wp_ajax_pcm_check_defensive_mode_status', 'pcm_ajax_check_defensive_mode_status' );
@@ -0,0 +1,73 @@
<?php // Pressable Cache Management - Exclude pages from Batcache
// disable direct file access
if (!defined('ABSPATH'))
{
exit;
}
$options = get_option('pressable_cache_management_options');
if (isset($options['exempt_from_batcache']) && !empty($options['exempt_from_batcache']))
{
//Create the pressable-cache-management mu-plugin index file
$pcm_mu_plugins_index = WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management.php';
if (!file_exists($pcm_mu_plugins_index)) {
// Copy pressable-cache-management.php from plugin directory to mu-plugins directory
copy( plugin_dir_path(__FILE__) . '/pressable_cache_management_mu_plugin_index.php', $pcm_mu_plugins_index);
}
// Check if the pressable-cache-management directory exists or create the folder
if (!file_exists(WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/')) {
//create the directory
wp_mkdir_p(WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/');
}
//Add the option from the textbox into the database
update_option('exempt_from_batcache', $options['exempt_from_batcache']);
// Exclude pages from Batcache
$obj_exclude_pages_from_batcache = WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/pcm_exclude_pages_from_batcache.php';
if (file_exists($obj_exclude_pages_from_batcache))
{
}
else
{
$obj_exclude_pages_from_batcache = plugin_dir_path(__FILE__) . '/exclude_pages_from_batcache_mu_plugin.php';
$obj_exclude_pages_from_batcache_active = WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/pcm_exclude_pages_from_batcache.php';
//Flush cache to enable activation take effect immediately
wp_cache_flush();
if (!copy($obj_exclude_pages_from_batcache, $obj_exclude_pages_from_batcache_active))
{
}
else
{
}
}
}
else
{
$obj_exclude_pages_from_batcache = WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/pcm_exclude_pages_from_batcache.php';
if (file_exists($obj_exclude_pages_from_batcache))
{
unlink($obj_exclude_pages_from_batcache);
//Flush cache to enable deactivation take effect immediately
wp_cache_flush();
}
else
{
// File not found.
}
}
@@ -0,0 +1,48 @@
<?php
// Plugin Name: Exclude website pages from the Batcache and Edge Cache
if (!defined('IS_PRESSABLE')) {
return;
}
add_action('init', 'cancel_the_cache');
function cancel_the_cache() {
if (!function_exists('batcache_cancel')) {
return;
}
$options = get_option('pressable_cache_management_options');
$exempted_pages = isset($options['exempt_from_batcache']) ? $options['exempt_from_batcache'] : '';
if (empty($exempted_pages)) {
return;
}
// Convert stored options into an array and trim spaces
$exempted_pages = array_map('trim', explode(',', $exempted_pages));
// Get current URI without query parameters
$uri = strtok($_SERVER["REQUEST_URI"], '?');
// Always exclude homepage if listed or explicitly requested
if ($uri === '/' && in_array('/', $exempted_pages)) {
batcache_cancel();
disable_edge_cache();
return;
}
// Loop through exempted pages
foreach ($exempted_pages as $page) {
// Match exact page or paginated versions (e.g., /about/, /about/page/2/)
if ($uri === $page || preg_match("#^" . preg_quote($page, '#') . "(/page/\d+/?)?$#i", $uri)) {
batcache_cancel();
disable_edge_cache();
return;
}
}
}
function disable_edge_cache() {
header("Cache-Control: no-store, no-cache, must-revalidate, max-age=0");
}
@@ -0,0 +1,122 @@
<?php // Pressable Cache Management - Exclude Google Ads URL's with query string gclid from Batcache
// disable direct file access
if (!defined('ABSPATH'))
{
exit;
}
$options = get_option('pressable_cache_management_options');
if (isset($options['exclude_query_string_gclid_checkbox']) && !empty($options['exclude_query_string_gclid_checkbox']))
{
//Create the pressable-cache-management mu-plugin index file
$pcm_mu_plugins_index = WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management.php';
if (!file_exists($pcm_mu_plugins_index)) {
// Copy pressable-cache-management.php from plugin directory to mu-plugins directory
copy( plugin_dir_path(__FILE__) . '/pressable_cache_management_mu_plugin_index.php', $pcm_mu_plugins_index);
}
// Check if the pressable-cache-management directory exists or create the folder
if (!file_exists(WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/')) {
//create the directory
wp_mkdir_p(WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/');
}
//Declear variable so that it can be accessed from
$exclude_query_string_gclid = get_option('exclude_query_string_gclid');
// Exclude Google Ads URL's with query string gclid from Batcache
$obj_exclude_query_string_gclid = WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/pcm_exclude_query_string_gclid.php';
if (file_exists($obj_exclude_query_string_gclid))
{
}
else
{
$obj_exclude_query_string_gclid = plugin_dir_path(__FILE__) . '/exclude_query_string_gclid_from_cache_mu_plugin.php';
$obj_exclude_query_string_gclid_active = WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/pcm_exclude_query_string_gclid.php';
//Flush cache to enable activation take effect immediately
wp_cache_flush();
if (!copy($obj_exclude_query_string_gclid, $obj_exclude_query_string_gclid_active))
{
}
else
{
}
}
//Display admin notice
function exclude_query_string_gclid_admin_notice($message = '', $classes = 'notice-success')
{
if (!empty($message))
{
printf('<div class="notice %2$s">%1$s</div>', $message, $classes);
}
}
function pcm_exclude_query_string_gclid_admin_notice()
{
$exclude_query_string_gclid_activate_display_notice = get_option('exclude_query_string_gclid_activate_notice', 'activating');
if ('activating' === $exclude_query_string_gclid_activate_display_notice && current_user_can('manage_options'))
{
add_action('admin_notices', function ()
{
$screen = get_current_screen();
//Display admin notice for this plugin page only
if ($screen->id !== 'toplevel_page_pressable_cache_management') return;
$user = $GLOBALS['current_user'];
$message = sprintf('<p> Google Ads URL with query string (gclid) will be excluded from Batcache.</p>', $user->display_name);
exclude_query_string_gclid_admin_notice($message, 'notice notice-success is-dismissible');
});
update_option('exclude_query_string_gclid_activate_notice', 'activated');
}
}
add_action('init', 'pcm_exclude_query_string_gclid_admin_notice');
}
else
{
/**Update option from the database if the option is deactivated
used by admin notice to display and remove notice**/
update_option('exclude_query_string_gclid_activate_notice', 'activating');
$obj_exclude_query_string_gclid = WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/pcm_exclude_query_string_gclid.php';
if (file_exists($obj_exclude_query_string_gclid))
{
unlink($obj_exclude_query_string_gclid);
//Flush cache to enable deactivation take effect immediately
wp_cache_flush();
}
else
{
// File not found.
}
}
@@ -0,0 +1,25 @@
<?php // Pressable Cache Management - Exclude Google Ads URL with query string gclid from Batcache
// disable direct file access
if (!defined('ABSPATH'))
{
exit;
}
/**
* Batcache by default will create a new cached page for each query parameter
* But we want to ignore Google Ads with the URL Param of gclid
**/
if (!function_exists('exclude_gclid_from_batcache')) {
function exclude_gclid_from_batcache() {
global $batcache;
if ( is_object( $batcache ) ) {
$batcache->ignored_query_args = array( 'gclid' );
}
}
}
add_action( 'plugins_loaded', 'exclude_gclid_from_batcache' );
@@ -0,0 +1,50 @@
<?php
// Pressable Cache Management - Extend batcache by 24 hours
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$options = get_option( 'pressable_cache_management_options' );
if ( isset( $options['extend_batcache_checkbox'] ) && ! empty( $options['extend_batcache_checkbox'] ) ) {
update_option( 'extend_batcache_checkbox', $options['extend_batcache_checkbox'] );
$extend_batcache = get_option( 'extend_batcache_checkbox' );
// Create the mu-plugin index file if it doesn't exist
$pcm_mu_plugins_index = WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management.php';
if ( ! file_exists( $pcm_mu_plugins_index ) ) {
copy( plugin_dir_path( __FILE__ ) . '/pressable_cache_management_mu_plugin_index.php', $pcm_mu_plugins_index );
}
// Ensure mu-plugins directory exists
if ( ! file_exists( WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/' ) ) {
wp_mkdir_p( WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/' );
}
$obj_extend_batcache = WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/pcm_extend_batcache.php';
$obj_extend_batcache_source = plugin_dir_path( __FILE__ ) . '/extend_batcache_mu_plugin.php';
$obj_extend_batcache_active = $obj_extend_batcache;
if ( ! file_exists( $obj_extend_batcache ) ) {
// mu-plugin doesn't exist yet — this is a FRESH enable, copy file and queue notice
wp_cache_flush();
if ( copy( $obj_extend_batcache_source, $obj_extend_batcache_active ) ) {
// Mark notice as pending — will show ONCE on next admin page load, then clear itself
update_option( 'pcm_extend_batcache_notice_pending', '1' );
}
}
// If file already exists: checkbox was already on before this load — do NOT re-queue notice
} else {
// Checkbox is OFF — clear the notice flag and remove the mu-plugin
delete_option( 'pcm_extend_batcache_notice_pending' );
$obj_extend_batcache = WP_CONTENT_DIR . '/mu-plugins/pressable-cache-management/pcm_extend_batcache.php';
if ( file_exists( $obj_extend_batcache ) ) {
unlink( $obj_extend_batcache );
wp_cache_flush();
}
}
@@ -0,0 +1,18 @@
<?php // Extend Batcache for Pressable site
if (!defined('IS_PRESSABLE'))
{
return;
}
//Batcache Customizations
global $batcache;
//Check is batcache params are in an object or an array, apply customizations accordingly
if ( is_object( $batcache ) ) {
$batcache->max_age = 86400; // Seconds the cached render of a page will be stored
$batcache->seconds = 1200; // The amount of time at least 2 people are required to
} elseif ( is_array( $batcache ) ) {
$batcache['max_age'] = 86400; // Seconds the cached render of a page will be stored
$batcache['seconds'] = 1200;// The amount of time at least 2 people are required to
}
@@ -0,0 +1,139 @@
<?php
/**
* Pressable Cache Management - Flush cache for a particular page (column link)
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$options = get_option( 'pressable_cache_management_options' );
if ( isset( $options['flush_object_cache_for_single_page'] ) && ! empty( $options['flush_object_cache_for_single_page'] ) ) {
add_action( 'init', 'pcm_show_flush_cache_column' );
function pcm_show_flush_cache_column() {
if ( current_user_can('administrator') || current_user_can('editor') || current_user_can('manage_woocommerce') ) {
$column = new FlushObjectCachePageColumn();
$column->add();
}
}
function flush_object_cache_for_single_page_notice() {
$state = get_option( 'flush-object-cache-for-single-page-notice', 'activating' );
if ( 'activating' === $state &&
( current_user_can('administrator') || current_user_can('editor') || current_user_can('manage_woocommerce') )
) {
add_action( 'admin_notices', function() {
$screen = get_current_screen();
if ( ! isset( $screen ) || $screen->id !== 'toplevel_page_pressable_cache_management' ) return;
$wrap = 'display:flex;align-items:center;justify-content:space-between;gap:12px;'
. 'border-left:4px solid #03fcc2;background:#fff;border-radius:0 8px 8px 0;'
. 'padding:14px 18px;box-shadow:0 2px 8px rgba(4,0,36,.07);'
. 'margin:10px 0;font-family:sans-serif;';
$btn = 'background:none;border:none;cursor:pointer;color:#94a3b8;font-size:18px;line-height:1;padding:0;';
$pcm_nid = 'pcm-sp-notice-' . substr( md5( microtime() ), 0, 8 );
echo '<div style="max-width:1120px;margin:0 auto;padding:0 20px;box-sizing:border-box;">';
echo '<div id="' . $pcm_nid . '" style="' . $wrap . '">';
echo '<p style="margin:0;font-size:13px;color:#040024;">'
. esc_html__( 'You can Flush Cache for Individual page or post from page preview.', 'pressable_cache_management' )
. '</p>';
echo '<button type="button" onclick="document.getElementById(\'' . $pcm_nid . '\').remove();" style="' . $btn . '">&#x2297;</button>';
echo '</div>';
echo '</div>';
});
update_option( 'flush-object-cache-for-single-page-notice', 'activated' );
}
}
add_action( 'init', 'flush_object_cache_for_single_page_notice' );
} else {
update_option( 'flush-object-cache-for-single-page-notice', 'activating' );
}
// ─── FlushObjectCachePageColumn class ────────────────────────────────────────
if ( ! class_exists( 'FlushObjectCachePageColumn' ) ) {
class FlushObjectCachePageColumn {
public function __construct() {}
public function add() {
add_filter( 'post_row_actions', array( $this, 'add_flush_object_cache_link' ), 10, 2 );
add_filter( 'page_row_actions', array( $this, 'add_flush_object_cache_link' ), 10, 2 );
add_action( 'admin_enqueue_scripts', array( $this, 'load_js' ) );
add_action( 'wp_ajax_pcm_flush_object_cache_column', array( $this, 'flush_object_cache_column' ) );
}
public function add_flush_object_cache_link( $actions, $post ) {
if ( current_user_can('administrator') || current_user_can('editor') || current_user_can('manage_woocommerce') ) {
$actions['flush_object_cache_url'] =
'<a data-id="' . esc_attr( $post->ID ) . '"'
. ' data-nonce="' . wp_create_nonce( 'flush-object-cache_' . $post->ID ) . '"'
. ' id="flush-object-cache-url-' . esc_attr( $post->ID ) . '"'
. ' style="cursor:pointer;">'
. esc_html__( 'Flush Cache', 'pressable_cache_management' ) . '</a>';
}
return $actions;
}
public function flush_object_cache_column() {
if ( ! ( current_user_can('administrator') || current_user_can('editor') || current_user_can('manage_woocommerce') ) ) {
die( json_encode( array( 'success' => false, 'message' => 'Unauthorized' ) ) );
}
if ( ! isset( $_GET['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['nonce'] ) ), 'flush-object-cache_' . intval( $_GET['id'] ) ) ) {
die( json_encode( array( 'success' => false, 'message' => 'Nonce verification failed' ) ) );
}
$url_key = get_permalink( intval( $_GET['id'] ) );
$page_title = get_the_title( intval( $_GET['id'] ) );
update_option( 'page-title', $page_title );
global $batcache, $wp_object_cache;
if ( ! isset( $batcache ) || ! is_object( $batcache ) || ! method_exists( $wp_object_cache, 'incr' ) ) {
die( json_encode( array( 'success' => false ) ) );
}
$batcache->configure_groups();
$url = apply_filters( 'batcache_manager_link', $url_key );
if ( empty( $url ) ) {
die( json_encode( array( 'success' => false ) ) );
}
do_action( 'batcache_manager_before_flush', $url );
$url = set_url_scheme( $url, 'http' );
$url_key = md5( $url );
wp_cache_add( "{$url_key}_version", 0, $batcache->group );
wp_cache_incr( "{$url_key}_version", 1, $batcache->group );
if ( property_exists( $wp_object_cache, 'no_remote_groups' ) ) {
$k = array_search( $batcache->group, (array) $wp_object_cache->no_remote_groups );
if ( false !== $k ) {
unset( $wp_object_cache->no_remote_groups[ $k ] );
wp_cache_set( "{$url_key}_version", $batcache->group );
$wp_object_cache->no_remote_groups[ $k ] = $batcache->group;
}
}
do_action( 'batcache_manager_after_flush', $url );
update_option( 'flush-object-cache-for-single-page-time-stamp', gmdate( 'j M Y, g:ia' ) . ' UTC' );
// Also store the flushed URL so it shows on the settings page
update_option( 'single-page-url-flushed', $url );
die( json_encode( array( 'success' => true ) ) );
}
public function load_js() {
wp_enqueue_script(
'flush-object-cache-column',
plugin_dir_url( dirname( __FILE__ ) ) . 'public/js/column.js',
array(), time(), true
);
}
}
}
@@ -0,0 +1,100 @@
<?php
/**
* Pressable Cache Management — Flush Batcache for WooCommerce Individual Pages
*
* When enabled, copies pcm_batcache_manager.php into mu-plugins so that Batcache
* is flushed automatically for any individual page/product updated via WooCommerce API.
* When disabled, removes the mu-plugin file and restores the previous state.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$options = get_option( 'pressable_cache_management_options' );
$enabled = ! empty( $options['flush_batcache_for_woo_product_individual_page_checkbox'] );
$mu_plugin_dest = WP_CONTENT_DIR . '/mu-plugins/pcm_batcache_manager.php';
$mu_plugin_src = plugin_dir_path( __FILE__ ) . 'pcm_batcache_manager.php';
if ( $enabled ) {
// ── Feature ON ───────────────────────────────────────────────────────────
// Always sync the source file into mu-plugins so that any updates to
// pcm_batcache_manager.php (e.g. targeted flush fixes) take effect immediately.
// Previously this only copied on first enable, meaning edits to the source
// were never deployed to the live mu-plugin copy.
$needs_update = ! file_exists( $mu_plugin_dest )
|| ( file_exists( $mu_plugin_src ) && md5_file( $mu_plugin_src ) !== md5_file( $mu_plugin_dest ) );
if ( $needs_update && file_exists( $mu_plugin_src ) && @copy( $mu_plugin_src, $mu_plugin_dest ) ) {
if ( ! file_exists( $mu_plugin_dest ) ) {
// Only flush and show notice on fresh enable, not on every update
wp_cache_flush();
update_option( 'flush_batcache_for_woo_product_individual_page_activate_notice', 'activating' );
}
}
// ── Show branded activation notice (once, on next page load) ─────────────
add_action( 'init', 'pcm_woo_individual_page_activation_notice' );
function pcm_woo_individual_page_activation_notice() {
$state = get_option( 'flush_batcache_for_woo_product_individual_page_activate_notice', 'activated' );
if ( 'activating' !== $state || ! current_user_can( 'manage_options' ) ) {
return;
}
add_action( 'admin_notices', 'pcm_woo_individual_page_render_notice' );
update_option( 'flush_batcache_for_woo_product_individual_page_activate_notice', 'activated' );
}
function pcm_woo_individual_page_render_notice() {
$screen = get_current_screen();
if ( ! $screen || $screen->id !== 'toplevel_page_pressable_cache_management' ) {
return;
}
$nid = 'pcm-woo-notice-' . substr( md5( microtime() ), 0, 8 );
$wrap = 'display:flex;align-items:center;justify-content:space-between;gap:12px;'
. 'border-left:4px solid #03fcc2;background:#fff;border-radius:0 8px 8px 0;'
. 'padding:14px 18px;box-shadow:0 2px 8px rgba(4,0,36,.07);'
. 'margin:10px 0;font-family:sans-serif;';
$icon_wrap = 'display:flex;align-items:center;gap:10px;';
$icon = '<span style="display:inline-flex;align-items:center;justify-content:center;'
. 'width:32px;height:32px;border-radius:50%;background:#f0fdf9;flex-shrink:0;">'
. '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg">'
. '<path d="M8 1.5a6.5 6.5 0 100 13 6.5 6.5 0 000-13zM0 8a8 8 0 1116 0A8 8 0 010 8z" fill="#03fcc2"/>'
. '<path d="M8 7a1 1 0 011 1v3a1 1 0 11-2 0V8a1 1 0 011-1zM8 5.5a1 1 0 100-2 1 1 0 000 2z" fill="#03fcc2"/>'
. '</svg></span>';
$btn = 'background:none;border:none;cursor:pointer;color:#94a3b8;font-size:18px;'
. 'line-height:1;padding:0;flex-shrink:0;margin-top:2px;';
echo '<div style="max-width:1120px;margin:0 auto;padding:0 20px;box-sizing:border-box;">';
echo '<div id="' . esc_attr( $nid ) . '" style="' . $wrap . '">';
echo '<div style="' . $icon_wrap . '">' . $icon;
echo '<div>';
echo '<p style="margin:0 0 2px;font-size:13px;font-weight:600;color:#040024;">'
. esc_html__( 'Flush Batcache for WooCommerce Product Pages — Enabled', 'pressable_cache_management' )
. '</p>';
echo '<p style="margin:0;font-size:12px;color:#64748b;">'
. esc_html__( 'Automatically flush individual pages, including product pages updated via the WooCommerce API.', 'pressable_cache_management' )
. '</p>';
echo '</div></div>';
echo '<button type="button" onclick="document.getElementById(\'' . esc_js( $nid ) . '\').remove();" style="' . $btn . '">&#x2297;</button>';
echo '</div>';
echo '</div>';
}
} else {
// ── Feature OFF ──────────────────────────────────────────────────────────
// Reset so notice shows again next time it is re-enabled
update_option( 'flush_batcache_for_woo_product_individual_page_activate_notice', 'activating' );
if ( file_exists( $mu_plugin_dest ) ) {
@unlink( $mu_plugin_dest );
wp_cache_flush();
}
}
@@ -0,0 +1,28 @@
<?php // Pressable Cache Management - Flush cache when comment is deleted
$options = get_option('pressable_cache_management_options');
if (isset($options['flush_cache_on_comment_delete_checkbox']) && !empty($options['flush_cache_on_comment_delete_checkbox']))
{
add_action( 'trash_comment', 'pcm_trash_comment_action', 10, 2 );
/**
* Function for `trash_comment` action-hook.
*
* @param string $comment_id The comment ID as a numeric string.
* @param WP_Comment $comment The comment to be trashed.
*
* @return void
*/
function pcm_trash_comment_action( $comment_id, $comment ){
wp_cache_flush();
//Save time stamp to database if cache is flushed when comment is deleted.
$object_cache_flush_time = date(' jS F Y g:ia') . "\nUTC";
update_option('flush-cache-on-comment-delete-time-stamp', $object_cache_flush_time);
}
}
@@ -0,0 +1,96 @@
<?php
/**
* Pressable Cache Management — Flush Batcache for the individual page/post on edit.
*
* Instead of flushing the entire object cache on every save, this targets only
* the Batcache entry for the URL of the post that was just saved — the same
* technique used by flush_batcache_for_particular_page.php (column link) and
* flush_single_page_toolbar.php (toolbar button).
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$options = get_option( 'pressable_cache_management_options' );
if ( isset( $options['flush_cache_page_edit_checkbox'] ) && ! empty( $options['flush_cache_page_edit_checkbox'] ) ) {
/**
* Flush Batcache only for the URL of the post that was just saved.
*
* Fires on save_post (covers pages, posts, and all custom post types,
* including WooCommerce products saved via the REST API).
*
* @param int $post_id The saved post ID.
* @param WP_Post $post The saved post object.
* @param bool $update True if this is an update, false for a new post.
*/
function pcm_flush_batcache_on_page_edit( $post_id, $post, $update ) {
// Skip auto-saves, revisions, and non-published posts
if ( wp_is_post_autosave( $post_id ) || wp_is_post_revision( $post_id ) ) {
return;
}
if ( $post->post_status !== 'publish' ) {
return;
}
// Get the public URL for this post
$url = get_permalink( $post_id );
if ( empty( $url ) ) {
return;
}
global $batcache, $wp_object_cache;
// Batcache must be loaded and the object cache must support incr()
if ( ! isset( $batcache ) || ! is_object( $batcache ) || ! method_exists( $wp_object_cache, 'incr' ) ) {
return;
}
$batcache->configure_groups();
$url = apply_filters( 'batcache_manager_link', $url );
if ( empty( $url ) ) {
return;
}
do_action( 'batcache_manager_before_flush', $url );
// Batcache keys off the http:// version of the URL
$url = set_url_scheme( $url, 'http' );
$url_key = md5( $url );
// Increment the version key — Batcache treats the cached copy as stale
wp_cache_add( "{$url_key}_version", 0, $batcache->group );
wp_cache_incr( "{$url_key}_version", 1, $batcache->group );
// Handle sites where the Batcache group is excluded from remote sync
if ( property_exists( $wp_object_cache, 'no_remote_groups' ) ) {
$k = array_search( $batcache->group, (array) $wp_object_cache->no_remote_groups );
if ( false !== $k ) {
unset( $wp_object_cache->no_remote_groups[ $k ] );
wp_cache_set( "{$url_key}_version", $batcache->group );
$wp_object_cache->no_remote_groups[ $k ] = $batcache->group;
}
}
do_action( 'batcache_manager_after_flush', $url );
// Record the flush for display on the settings page
$post_type_obj = get_post_type_object( $post->post_type );
$post_type_name = $post_type_obj ? $post_type_obj->labels->singular_name : $post->post_type;
$stamp = gmdate( 'j M Y, g:ia' ) . ' UTC'
. '<b> — cache flushed for ' . esc_html( $post_type_name )
. ' edit: ' . esc_html( $post->post_title ) . '</b>';
update_option( 'flush-cache-page-edit-time-stamp', $stamp );
// Also write the flushed URL so the settings page can show it
update_option( 'single-page-url-flushed', $url );
}
add_action( 'save_post', 'pcm_flush_batcache_on_page_edit', 10, 3 );
}
@@ -0,0 +1,40 @@
<?php // Custom function - Add custom functions to flush cache when page or post is deleted
// disable direct file access
if (!defined('ABSPATH'))
{
exit;
}
$options = get_option('pressable_cache_management_options');
if (isset($options['flush_cache_on_page_post_delete_checkbox']) && !empty($options['flush_cache_on_page_post_delete_checkbox']))
{
function fire_on_page_post_delete( $post_ID, $post_after, $post_before ) {
if ( $post_after->post_status == 'trash' && $post_before->post_status == 'publish' ) {
// Flush site cache if post or page is trashed after publishing
wp_cache_flush();
}
if ( $post_after->post_status == 'publish' && $post_before->post_status == 'trash' ) {
// Flush site cache if post or page is published after being trash (post undelete)
wp_cache_flush();
}
// Save time stamp to database if cache is flushed when a post or page was daleted.
$object_cache_flush_time = date(' jS F Y g:ia') . "\nUTC";
update_option('flush-cache-on-page-post-delete-time-stamp', $object_cache_flush_time);
//Set transient for admin notice for 9 seconds
set_transient('pcm-page-post-delete-notice', true, 9);
}
add_action( 'post_updated', 'fire_on_page_post_delete', 10, 3 );
}
@@ -0,0 +1,76 @@
<?php
// Custom function - Flush cache automatically on themes and plugins update
if ( ! defined( 'ABSPATH' ) ) {
exit();
}
$options = get_option( 'pressable_cache_management_options' );
if ( isset( $options['flush_cache_theme_plugin_checkbox'] ) && ! empty( $options['flush_cache_theme_plugin_checkbox'] ) ) {
function pcm_plugins_themes_update_completed( $upgrader_object, $hook_extra ) {
$type = isset( $hook_extra['type'] ) ? $hook_extra['type'] : '';
if ( ! in_array( $type, array( 'plugin', 'theme' ), true ) ) {
return;
}
wp_cache_flush();
// ── Resolve the name of the updated item ────────────────────────────
$name = '';
// Multiple plugins updated at once
if ( $type === 'plugin' && isset( $hook_extra['plugins'] ) && is_array( $hook_extra['plugins'] ) ) {
$names = array();
foreach ( $hook_extra['plugins'] as $plugin_file ) {
$plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin_file, false, false );
if ( ! empty( $plugin_data['Name'] ) ) {
$names[] = $plugin_data['Name'];
}
}
$name = ! empty( $names ) ? implode( ', ', $names ) : 'Unknown plugin';
}
// Single plugin
if ( $type === 'plugin' && empty( $name ) ) {
if ( isset( $hook_extra['plugin'] ) ) {
$plugin_data = get_plugin_data( WP_PLUGIN_DIR . '/' . $hook_extra['plugin'], false, false );
$name = ! empty( $plugin_data['Name'] ) ? $plugin_data['Name'] : $hook_extra['plugin'];
} elseif ( isset( $upgrader_object->skin->plugin_info['Name'] ) ) {
$name = $upgrader_object->skin->plugin_info['Name'];
} else {
$name = 'Unknown plugin';
}
}
// Theme
if ( $type === 'theme' ) {
if ( isset( $hook_extra['themes'] ) && is_array( $hook_extra['themes'] ) ) {
$theme_names = array();
foreach ( $hook_extra['themes'] as $stylesheet ) {
$theme = wp_get_theme( $stylesheet );
if ( $theme->exists() ) {
$theme_names[] = $theme->get('Name');
}
}
$name = ! empty( $theme_names ) ? implode( ', ', $theme_names ) : 'Unknown theme';
} elseif ( isset( $hook_extra['theme'] ) ) {
$theme = wp_get_theme( $hook_extra['theme'] );
$name = $theme->exists() ? $theme->get('Name') : $hook_extra['theme'];
} elseif ( isset( $upgrader_object->skin->theme_info['Name'] ) ) {
$name = $upgrader_object->skin->theme_info['Name'];
} else {
$name = 'Unknown theme';
}
}
// ── Build timestamp with bold item name ──────────────────────────────
$timestamp = gmdate( 'j M Y, g:ia' ) . ' UTC — <b>' . esc_html( $name ) . ' ' . esc_html( $type ) . ' was updated</b>';
update_option( 'flush-cache-theme-plugin-time-stamp', $timestamp );
}
add_action( 'upgrader_process_complete', 'pcm_plugins_themes_update_completed', 10, 2 );
}
@@ -0,0 +1,70 @@
<?php
/**
* Pressable Cache Management - Flush Object Cache + Page Cache
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( isset( $_POST['flush_object_cache_nonce'] ) ) {
function pressable_cache_button() {
if ( ! wp_verify_nonce(
sanitize_text_field( wp_unslash( $_POST['flush_object_cache_nonce'] ) ),
'flush_object_cache_nonce'
) || ! current_user_can( 'manage_options' ) ) {
return;
}
// Flush WP Object Cache (Redis / Memcached)
wp_cache_flush();
// Flush Batcache page cache if available
if ( function_exists( 'batcache_clear_cache' ) ) {
batcache_clear_cache();
}
// WP Super Cache
if ( function_exists( 'wp_cache_clear_cache' ) ) {
wp_cache_clear_cache();
}
// W3 Total Cache
if ( function_exists( 'w3tc_flush_all' ) ) {
w3tc_flush_all();
}
// WP Rocket
if ( function_exists( 'rocket_clean_domain' ) ) {
rocket_clean_domain();
}
// Custom hook for other integrations
do_action( 'pcm_flush_all_cache' );
// Clear the cached Batcache status so the badge refreshes on next page load
do_action( 'pcm_after_object_cache_flush' );
delete_transient( 'pcm_batcache_status' );
}
add_action( 'wp_before_admin_bar_render', 'pressable_cache_button', 999 );
// Branded success notice - only show ONE (remove WP default)
function flush_cache_notice__success() {
$pcm_nid = 'pcm-obj-notice-' . substr( md5( microtime() ), 0, 8 );
$wrap = 'display:flex;align-items:center;justify-content:space-between;gap:12px;'
. 'border-left:4px solid #03fcc2;background:#fff;border-radius:0 8px 8px 0;'
. 'padding:14px 18px;box-shadow:0 2px 8px rgba(4,0,36,.07);'
. 'margin:10px 20px 10px 0;font-family:sans-serif;';
$btn = 'background:none;border:none;cursor:pointer;color:#94a3b8;font-size:18px;line-height:1;padding:0;';
echo '<div id="' . $pcm_nid . '" style="' . $wrap . '">';
echo '<p style="margin:0;font-size:13px;color:#040024;">'
. esc_html__( 'Object Cache Flushed Successfully.', 'pressable_cache_management' )
. '</p>';
echo '<button type="button" onclick="document.getElementById(\'' . $pcm_nid . '\').remove();" style="' . $btn . '">&#x2297;</button>';
echo '</div>';
}
add_action( 'admin_notices', 'flush_cache_notice__success' );
update_option( 'flush-obj-cache-time-stamp', gmdate( 'j M Y, g:ia' ) . ' UTC' );
}
@@ -0,0 +1,214 @@
<?php
/**
* Pressable Cache Management - Flush Batcache for Individual Page from toolbar
* Sourced from official repo flush_single_page_toolbar.php with branded notices.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
$options = get_option( 'pressable_cache_management_options' );
if ( isset( $options['flush_object_cache_for_single_page'] ) && ! empty( $options['flush_object_cache_for_single_page'] ) ) {
if ( ! class_exists( 'PcmFlushCacheAdminbar' ) ) {
class PcmFlushCacheAdminbar {
public function __construct() {}
public function add() {
if ( is_admin() ) {
add_action( 'wp_before_admin_bar_render', array( $this, 'PcmFlushCacheAdminbar' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'load_toolbar_js' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'load_remove_branding_toolbar_js' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'load_toolbar_css' ) );
} else {
if ( is_admin() || is_admin_bar_showing() ) {
add_action( 'wp_before_admin_bar_render', array( $this, 'pcm_toolbar_for_page_preview' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'load_toolbar_js' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'load_remove_branding_toolbar_js' ) );
add_action( 'wp_enqueue_scripts', array( $this, 'load_toolbar_css' ) );
add_action( 'wp_footer', array( $this, 'print_my_inline_script' ) );
}
}
// AJAX: flush batcache for current page
add_action( 'wp_ajax_pcm_delete_current_page_cache', array( $this, 'pcm_delete_current_page_cache' ) );
// AJAX: purge edge cache for current page
add_action( 'wp_ajax_pcm_purge_current_page_edge_cache', array( $this, 'pcm_purge_current_page_edge_cache' ) );
}
public function pcm_delete_current_page_cache() {
if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['nonce'] ) ), 'pcm_nonce' ) ) {
die( json_encode( array( 'Security Error!', 'error', 'alert' ) ) );
}
global $batcache, $wp_object_cache;
if ( ! isset( $batcache ) || ! is_object( $batcache ) || ! method_exists( $wp_object_cache, 'incr' ) ) {
return;
}
$batcache->configure_groups();
$path = urldecode( esc_url_raw( wp_unslash( $_GET['path'] ) ) );
if ( preg_match( '/\.{2,}/', $path ) ) {
die( 'Suspected Directory Traversal Attack' );
}
$url = get_home_url() . $path;
$url = apply_filters( 'batcache_manager_link', $url );
if ( empty( $url ) ) return false;
do_action( 'batcache_manager_before_flush', $url );
$url = set_url_scheme( $url, 'http' );
update_option( 'single-page-url-flushed', $url );
$url_key = md5( $url );
if ( is_object( $batcache ) ) {
wp_cache_add( "{$url_key}_version", 0, $batcache->group );
wp_cache_incr( "{$url_key}_version", 1, $batcache->group );
}
if ( property_exists( $wp_object_cache, 'no_remote_groups' ) ) {
$k = array_search( $batcache->group, (array) $wp_object_cache->no_remote_groups );
if ( false !== $k ) {
unset( $wp_object_cache->no_remote_groups[ $k ] );
wp_cache_set( "{$url_key}_version", $batcache->group );
$wp_object_cache->no_remote_groups[ $k ] = $batcache->group;
}
}
do_action( 'batcache_manager_after_flush', $url );
update_option( 'flush-object-cache-for-single-page-time-stamp', gmdate( 'j M Y, g:ia' ) . ' UTC' );
wp_send_json_success( array( 'flushed' => 'batcache' ) );
}
public function pcm_purge_current_page_edge_cache() {
if ( ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['nonce'] ) ), 'pcm_nonce' ) ) {
die( json_encode( array( 'Security Error!', 'error', 'alert' ) ) );
}
$path = urldecode( esc_url_raw( wp_unslash( $_GET['path'] ) ) );
if ( preg_match( '/\.{2,}/', $path ) ) {
die( 'Suspected Directory Traversal Attack' );
}
$url = get_home_url() . $path;
update_option( 'edge-cache-single-page-url-purged', $url );
if ( empty( $url ) ) return false;
if ( class_exists( 'Edge_Cache_Plugin' ) ) {
$edge_cache = Edge_Cache_Plugin::get_instance();
$result = $edge_cache->purge_uris_now( array( $url ) );
update_option( 'single-page-edge-cache-purge-time-stamp', gmdate( 'j M Y, g:ia' ) . ' UTC' );
wp_send_json_success( array( 'flushed' => 'edge-cache' ) );
}
wp_send_json_error( array( 'reason' => 'Edge_Cache_Plugin not available' ) );
}
public function load_toolbar_css() {
wp_enqueue_style( 'pressable-cache-management-toolbar',
plugin_dir_url( dirname( __FILE__ ) ) . 'public/css/toolbar.css',
array(), time(), 'all' );
}
public function load_toolbar_js() {
wp_enqueue_script( 'pcm-toolbar',
plugin_dir_url( dirname( __FILE__ ) ) . 'public/js/toolbar.js',
array( 'jquery' ), time(), true );
// Pass nonce and edge-cache state to JS for BOTH admin and frontend contexts.
// pcm_nonce from print_my_inline_script() only runs on wp_footer (frontend).
// wp_localize_script covers both admin and frontend reliably.
$edge_on = ( get_option('edge-cache-enabled') === 'enabled' ) ? '1' : '0';
wp_localize_script( 'pcm-toolbar', 'pcmToolbarData', array(
'nonce' => wp_create_nonce( 'pcm_nonce' ),
'ajaxurl' => admin_url( 'admin-ajax.php' ),
'flushEdge'=> $edge_on,
) );
}
public function load_remove_branding_toolbar_js() {
wp_enqueue_script( 'pcm-toolbar-branding',
plugin_dir_url( dirname( __FILE__ ) ) . 'public/js/toolbar_remove_branding.js',
array( 'jquery' ), time(), true );
}
public function print_my_inline_script() { ?>
<script>
var pcm_ajaxurl = "<?php echo esc_url( admin_url('admin-ajax.php') ); ?>";
var pcm_nonce = "<?php echo wp_create_nonce('pcm_nonce'); ?>";
</script>
<?php
}
public function pcm_toolbar_for_page_preview() {
global $wp_admin_bar;
$branding_opts = get_option( 'remove_pressable_branding_tab_options' );
$branding_disabled = $branding_opts && 'disable' == $branding_opts['branding_on_off_radio_button'];
$edge_cache_on = ( get_option('edge-cache-enabled') === 'enabled' );
// Single label: include Edge Cache in the title when it is active
$flush_label = $edge_cache_on
? __( 'Flush Cache for This Page', 'pressable_cache_management' )
: __( 'Flush Batcache for This Page', 'pressable_cache_management' );
if ( $branding_disabled ) {
$parent = 'pcm-toolbar-parent-remove-branding';
$wp_admin_bar->add_node( array(
'id' => $parent,
'title' => __( 'Flush Cache', 'pressable_cache_management' ),
'class' => 'pcm-toolbar-child',
));
// Combined item — JS fires both Batcache + Edge Cache flushes in sequence
$wp_admin_bar->add_menu( array(
'id' => 'pcm-toolbar-parent-remove-branding-flush-cache-of-this-page',
'title' => $flush_label,
'parent' => $parent,
'meta' => array( 'class' => 'pcm-toolbar-child' ),
));
} else {
$parent = 'pcm-toolbar-parent';
$wp_admin_bar->add_node( array(
'id' => $parent,
'title' => __( 'Flush Cache', 'pressable_cache_management' ),
));
// Combined item — JS fires both Batcache + Edge Cache flushes in sequence
$wp_admin_bar->add_menu( array(
'id' => 'pcm-toolbar-parent-flush-cache-of-this-page',
'title' => $flush_label,
'parent' => $parent,
'meta' => array( 'class' => 'pcm-toolbar-child' ),
));
}
}
// Empty admin-side toolbar (handled by object_cache_admin_bar.php)
public function PcmFlushCacheAdminbar() {}
}
}
add_action( 'init', 'pcm_show_flush_cache_option_for_single_page' );
function pcm_show_flush_cache_option_for_single_page() {
$current_user = wp_get_current_user();
if ( current_user_can('manage_woocommerce') || current_user_can('administrator') ) {
$toolbar = new PcmFlushCacheAdminbar();
$toolbar->add();
} else {
if ( ! function_exists('load_admin_toolbar_css') ) {
function load_admin_toolbar_css() {
wp_enqueue_style( 'pressable-cache-management-toolbar',
plugin_dir_url( dirname( __FILE__ ) ) . 'public/css/toolbar.css',
array(), time(), 'all' );
}
}
add_action( 'init', 'load_admin_toolbar_css' );
}
}
}
@@ -0,0 +1,240 @@
<?php
/**
* Pressable Cache Management - Admin Bar Cache Buttons
* Branded popup notices matching plugin theme (#dd3a03, #040024, #03fcc2)
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// ─── Branded modal popup (replaces browser alert) ─────────────────────────
add_action( 'admin_footer', 'pcm_abar_modal_html' );
function pcm_abar_modal_html() {
if ( ! pcm_abar_can_view() ) return;
?>
<div id="pcm-modal-overlay" style="display:none;position:fixed;inset:0;background:rgba(4,0,36,.45);z-index:999999;align-items:center;justify-content:center;">
<div style="background:#fff;border-radius:12px;padding:28px 32px;max-width:440px;width:90%;box-shadow:0 8px 40px rgba(4,0,36,.18);font-family:sans-serif;position:relative;">
<div style="width:48px;height:4px;background:#03fcc2;border-radius:4px;margin-bottom:18px;"></div>
<div id="pcm-modal-message" style="font-size:14px;color:#040024;line-height:1.6;white-space:pre-line;margin-bottom:22px;"></div>
<button id="pcm-modal-ok" style="background:#dd3a03;color:#fff;border:none;border-radius:8px;padding:10px 28px;font-size:13.5px;font-weight:700;cursor:pointer;font-family:sans-serif;letter-spacing:.4px;transition:background .2s;">OK</button>
</div>
</div>
<script>
(function($){
function pcmShowModal(msg) {
$('#pcm-modal-message').text(msg);
$('#pcm-modal-overlay').css('display','flex');
}
$('#pcm-modal-ok, #pcm-modal-overlay').on('click', function(e){
if (e.target === this) $('#pcm-modal-overlay').hide();
});
$('#pcm-modal-ok').hover(
function(){ $(this).css('background','#b82f00'); },
function(){ $(this).css('background','#dd3a03'); }
);
window.pcmShowModal = pcmShowModal;
})(jQuery);
</script>
<?php
}
// ─── JS: Flush Object Cache ────────────────────────────────────────────────
add_action( 'admin_footer', 'pcm_abar_object_js' );
function pcm_abar_object_js() { ?>
<script>
jQuery(document).ready(function($){
$('li#wp-admin-bar-cache-purge .ab-item').on('click', function(e){
e.preventDefault();
$.post(ajaxurl, { action: 'flush_pressable_cache' }, function(r){
window.pcmShowModal(r.trim());
});
});
});
</script>
<?php }
// ─── JS: Purge Edge Cache ──────────────────────────────────────────────────
add_action( 'admin_footer', 'pcm_abar_edge_js' );
function pcm_abar_edge_js() { ?>
<script>
jQuery(document).ready(function($){
$('li#wp-admin-bar-edge-purge .ab-item').on('click', function(e){
e.preventDefault();
$.ajax({ url: ajaxurl, type: 'POST', data: { action: 'pressable_edge_cache_purge' },
success: function(r){ window.pcmShowModal(r.trim()); },
error: function(){ window.pcmShowModal('An error occurred during the Edge Cache purge request.'); }
});
});
});
</script>
<?php }
// ─── JS: Flush Object + Edge Cache ────────────────────────────────────────
add_action( 'admin_footer', 'pcm_abar_combined_js' );
function pcm_abar_combined_js() { ?>
<script>
jQuery(document).ready(function($){
$('li#wp-admin-bar-combined-cache-purge .ab-item').on('click', function(e){
e.preventDefault();
$.ajax({ url: ajaxurl, type: 'POST', data: { action: 'flush_combined_cache' },
success: function(r){ window.pcmShowModal(r.trim()); },
error: function(){ window.pcmShowModal('An error occurred during the combined cache flush.'); }
});
});
});
</script>
<?php }
// ─── Enqueue toolbar CSS ───────────────────────────────────────────────────
function pcm_abar_load_css() {
wp_enqueue_style( 'pressable-cache-management-toolbar',
plugin_dir_url( dirname( __FILE__ ) ) . 'public/css/toolbar.css',
array(), time(), 'all' );
}
add_action( 'init', 'pcm_abar_load_css' );
// ─── AJAX Hooks ───────────────────────────────────────────────────────────
add_action( 'wp_ajax_flush_pressable_cache', 'pcm_abar_flush_object_callback' );
add_action( 'wp_ajax_pressable_edge_cache_purge', 'pcm_abar_purge_edge_callback' );
add_action( 'wp_ajax_flush_combined_cache', 'pcm_abar_flush_combined_callback' );
function pcm_abar_flush_object_callback() {
if ( ! current_user_can('administrator') && ! current_user_can('editor') && ! current_user_can('manage_woocommerce') ) {
echo 'You do not have permission to flush the Object Cache.';
wp_die();
}
wp_cache_flush();
if ( function_exists('batcache_clear_cache') ) batcache_clear_cache();
update_option( 'flush-obj-cache-time-stamp', gmdate('j M Y, g:ia') . ' UTC' );
echo esc_html__( 'Object Cache Flushed successfully.', 'pressable_cache_management' );
wp_die();
}
function pcm_abar_purge_edge_callback() {
if ( ! current_user_can('administrator') && ! current_user_can('editor') && ! current_user_can('manage_woocommerce') ) {
echo 'You do not have permission to purge the Edge Cache.';
wp_die();
}
if ( ! class_exists('Edge_Cache_Plugin') ) {
echo esc_html__( 'Error: Edge Cache Plugin is not active. Purge aborted.', 'pressable_cache_management' );
wp_die();
}
$edge_cache = Edge_Cache_Plugin::get_instance();
if ( ! method_exists( $edge_cache, 'purge_domain_now' ) ) {
echo esc_html__( 'Error: Edge Cache purge method unavailable.', 'pressable_cache_management' );
wp_die();
}
$result = $edge_cache->purge_domain_now( 'admin-bar-edge-purge' );
if ( $result ) {
update_option( 'edge-cache-purge-time-stamp', gmdate('j M Y, g:ia') . ' UTC' );
echo esc_html__( 'Edge Cache purged successfully.', 'pressable_cache_management' );
} else {
echo esc_html__( 'Edge Cache purge failed. It might be disabled or rate-limited.', 'pressable_cache_management' );
}
wp_die();
}
function pcm_abar_flush_combined_callback() {
if ( ! current_user_can('administrator') && ! current_user_can('editor') && ! current_user_can('manage_woocommerce') ) {
echo 'You do not have permission to flush the combined cache.';
wp_die();
}
$messages = array();
// Object cache
wp_cache_flush();
if ( function_exists('batcache_clear_cache') ) batcache_clear_cache();
update_option( 'flush-obj-cache-time-stamp', gmdate('j M Y, g:ia') . ' UTC' );
$messages[] = esc_html__( 'Object Cache Flushed successfully.', 'pressable_cache_management' );
// Edge cache
if ( class_exists('Edge_Cache_Plugin') ) {
$edge_cache = Edge_Cache_Plugin::get_instance();
if ( method_exists( $edge_cache, 'purge_domain_now' ) ) {
$result = $edge_cache->purge_domain_now( 'admin-bar-combined-purge' );
if ( $result ) {
update_option( 'edge-cache-purge-time-stamp', gmdate('j M Y, g:ia') . ' UTC' );
$messages[] = esc_html__( 'Edge Cache Purged successfully.', 'pressable_cache_management' );
} else {
$messages[] = esc_html__( 'Edge Cache purge failed (possibly disabled or rate-limited).', 'pressable_cache_management' );
}
} else {
$messages[] = esc_html__( 'Edge Cache Plugin active, but purge method unavailable.', 'pressable_cache_management' );
}
} else {
$messages[] = esc_html__( 'Edge Cache Plugin not found; skipping Edge Cache purge.', 'pressable_cache_management' );
}
echo '- ' . implode( "\n- ", $messages );
wp_die();
}
// ─── Permission check ─────────────────────────────────────────────────────
if ( ! function_exists('pcm_abar_can_view') ) {
function pcm_abar_can_view() {
return current_user_can('administrator') || current_user_can('editor') || current_user_can('manage_woocommerce');
}
}
// ─── Admin Bar Menu ───────────────────────────────────────────────────────
add_action( 'admin_bar_menu', 'pcm_abar_add_menu', 100 );
function pcm_abar_add_menu( $wp_admin_bar ) {
if ( is_network_admin() || ! pcm_abar_can_view() ) return;
$branding_opts = get_option('remove_pressable_branding_tab_options');
$branding_disabled = $branding_opts && 'disable' == $branding_opts['branding_on_off_radio_button'];
$parent_id = $branding_disabled ? 'pcm-wp-admin-toolbar-parent-remove-branding' : 'pcm-wp-admin-toolbar-parent';
$parent_title = $branding_disabled ? 'Cache Control' : 'Cache Management';
// Detect Edge Cache state
$edge_cache_is_enabled = false;
if ( class_exists('Edge_Cache_Plugin') ) {
$ec = Edge_Cache_Plugin::get_instance();
$server_status = method_exists($ec,'get_ec_status') ? $ec->get_ec_status() : null;
if ( defined('Edge_Cache_Plugin::EC_ENABLED') && $server_status === Edge_Cache_Plugin::EC_ENABLED ) {
$edge_cache_is_enabled = true;
} elseif ( get_option('edge-cache-enabled') === 'enabled' ) {
$edge_cache_is_enabled = true;
}
}
// Parent
$wp_admin_bar->add_node( array( 'id' => $parent_id, 'title' => $parent_title ) );
// Flush Object Cache
$wp_admin_bar->add_menu( array(
'id' => 'cache-purge',
'title' => __( 'Flush Object Cache', 'pressable_cache_management' ),
'parent' => $parent_id,
'meta' => array( 'class' => 'pcm-wp-admin-toolbar-child' ),
));
// Edge Cache options (only if enabled)
if ( $edge_cache_is_enabled ) {
$wp_admin_bar->add_menu( array(
'id' => 'edge-purge',
'title' => __( 'Purge Edge Cache', 'pressable_cache_management' ),
'parent' => $parent_id,
'meta' => array( 'class' => 'pcm-wp-admin-toolbar-child' ),
));
$wp_admin_bar->add_menu( array(
'id' => 'combined-cache-purge',
'title' => __( 'Flush Object & Edge Cache', 'pressable_cache_management' ),
'parent' => $parent_id,
'meta' => array( 'class' => 'pcm-wp-admin-toolbar-child' ),
));
}
// Cache Settings (admin only)
if ( current_user_can('administrator') ) {
$wp_admin_bar->add_menu( array(
'id' => 'settings',
'title' => __( 'Cache Settings', 'pressable_cache_management' ),
'parent' => $parent_id,
'href' => admin_url('admin.php?page=pressable_cache_management'),
'meta' => array( 'class' => 'pcm-wp-admin-toolbar-child' ),
));
}
}
@@ -0,0 +1,486 @@
<?php
/*
* Plugin name: Batcache Manager
* Plugin URI: http://www.github.com/spacedmonkey/batcache-manager
* Description: Cache clearing for batcache
* Author: Jonathan Harris
* Author URI: http://www.jonathandavidharris.co.uk
* Version: 2.0.2
*/
/**
* Class Batcache_Manager
*/
class Batcache_Manager {
/**
* List of feeds
*
* @since 2.0.0
*
* @var array
*/
private $feeds = array( 'rss', 'rss2', 'rdf', 'atom' );
/**
* List of links to process
*
* @since 2.0.0
*
* @var array
*/
private $links = array();
/**
* Instance of this class.
*
* @since 2.0.0
*
* @var object
*/
protected static $instance = null;
/**
*
*/
private function __construct() {
global $batcache, $wp_object_cache;
// Do not load if our advanced-cache.php isn't loaded
if ( ! isset( $batcache ) || ! is_object( $batcache ) || ! method_exists( $wp_object_cache, 'incr' ) ) {
return;
}
$batcache->configure_groups();
// Posts
add_action( 'clean_post_cache', array( $this, 'action_clean_post_cache' ), 15 );
// Terms
add_action( 'clean_term_cache', array( $this, 'action_clean_term_cache' ), 10, 3 );
//Comments
add_action( 'clean_comment_cache', array( $this, 'action_update_comment' ) ); // Only supported in 4.5
add_action( 'comment_post', array( $this, 'action_update_comment' ) );
add_action( 'wp_set_comment_status', array( $this, 'action_update_comment' ) );
add_action( 'edit_comment', array( $this, 'action_update_comment' ) );
// Users
add_action( 'clean_user_cache', array( $this, 'action_update_user' ) );
add_action( 'profile_update', array( $this, 'action_update_user' ) );
// Widgets
add_filter( 'widget_update_callback', array( $this, 'action_update_widget' ), 50 );
// Customiser
add_action( 'customize_save_after', array( $this, 'flush_all' ) );
// Theme
add_action( 'switch_theme', array( $this, 'flush_all' ) );
// Nav
add_action( 'wp_update_nav_menu', array( $this, 'flush_all' ) );
// Add site aliases to list of links
add_filter( 'batcache_manager_links', array( $this, 'add_site_alias' ) );
// Do the flush of the urls on shutdown
add_action( 'shutdown', array( $this, 'clear_urls' ) );
}
/**
* Return an instance of this class.
*
* @since 2.0.0
*
* @return object A single instance of this class.
*/
public static function get_instance() {
// If the single instance hasn't been set, set it now.
if ( null == self::$instance ) {
self::$instance = new self;
}
return self::$instance;
}
/**
* Determines whether a post type is considered "viewable".
*
* For built-in post types such as posts and pages, the 'public' value will be evaluated.
* For all others, the 'publicly_queryable' value will be used.
*
*
* @param string $post_type Post type.
*
* @return bool Whether the post type should be considered viewable.
*/
public function is_post_type_viewable( $post_type ) {
$post_type_object = get_post_type_object( $post_type );
if ( empty( $post_type_object ) ) {
return false;
}
return $post_type_object->publicly_queryable || ( $post_type_object->_builtin && $post_type_object->public );
}
/**
* Whether the taxonomy object is public.
*
* Checks to make sure that the taxonomy is an object first. Then Gets the
* object, and finally returns the public value in the object.
*
* A false return value might also mean that the taxonomy does not exist.
*
* @since 2.0.0
*
* @param string $taxonomy Name of taxonomy object.
*
* @return bool Whether the taxonomy is public.
*/
function is_taxonomy_viewable( $taxonomy ) {
if ( ! taxonomy_exists( $taxonomy ) ) {
return false;
}
$taxonomy = get_taxonomy( $taxonomy );
return $taxonomy->public;
}
/**
* Clear post on post update
*
* @param $post_id
*/
public function action_clean_post_cache( $post_id ) {
$post = get_post( $post_id );
if ( $post && $post->post_type && ! $this->is_post_type_viewable( $post->post_type ) || ! in_array( get_post_status( $post_id ), array( 'publish', 'trash' ) ) ) {
return;
}
// Only flush the permalink of the specific post that changed.
// Date archives, author archives, feeds, and the homepage are intentionally
// NOT flushed here — those shared URLs should only be invalidated on a
// full manual flush, not on every individual page save.
$permalink = get_permalink( $post );
if ( ! empty( $permalink ) ) {
$this->links[] = $permalink;
}
// --- START OF MODIFIED CODE ---
// Check if the updated post is a WooCommerce product
if ( 'product' === $post->post_type ) {
$product_url = get_permalink( $post );
// 1. Flush the specific product URL (Batcache)
self::clear_url( $product_url );
// 2. Store the product URL in the option table
update_option( 'edge-cache-single-page-url-purged', $product_url );
// 3. Purge Edge Cache for the specific URL
if (class_exists('Edge_Cache_Plugin')) {
// Set the default timezone to UTC before calling date()
$timezone_backup = date_default_timezone_get();
date_default_timezone_set('UTC');
$edge_cache = Edge_Cache_Plugin::get_instance();
$urls = array($product_url);
// Use the correct method to purge URIs
$result = $edge_cache->purge_uris_now($urls);
// Save time stamp to database if edge cache is purged for particular page
$edge_cache_purge_time = date('jS F Y g:ia') . "\nUTC";
update_option('single-page-edge-cache-purge-time-stamp', $edge_cache_purge_time);
// Restore the original timezone
date_default_timezone_set($timezone_backup);
}
}
// --- END OF MODIFIED CODE ---
}
/**
* Clear terms on term update
*
* @param array $ids Single or list of Term IDs.
* @param string $taxonomy
* @param bool $clean_taxonomy Optional. Whether to clean taxonomy wide caches (true), or just individual
* term object caches (false). Default true. Only support in WP 4.5
*/
public function action_clean_term_cache( $ids, $taxonomy, $clean_taxonomy = true ) {
// Clear taxonomy global caches. If false, lets not both.
if ( ! $clean_taxonomy ) {
return;
}
// If not a public taxonomy, don't clear caches.
if ( ! $this->is_taxonomy_viewable( $taxonomy ) ) {
return;
}
foreach ( $ids as $term ) {
$this->setup_term_urls( $term, $taxonomy );
}
}
/**
* Clear post page on comment update
*
* @param $comment_id
*/
public function action_update_comment( $comment_id ) {
$comment = get_comment( $comment_id );
$post_id = $comment->comment_post_ID;
$this->setup_post_urls( $post_id );
$this->setup_post_comment_urls( $post_id, $comment_id );
}
/**
* Clear author links on update user.
*
* @param $user_id
*/
public function action_update_user( $user_id ) {
$this->setup_author_urls( $user_id );
}
public function flush_all() {
if ( function_exists( 'batcache_flush_all' ) ) {
batcache_flush_all();
}
}
/**
* Flush all of the caches when a widget is updated.
*
* @param array $instance The current widget instance's settings.
*
* @return array $instance
*/
public function action_update_widget( $instance ) {
$this->flush_all();
return $instance;
}
/**
* Get term archive and feed links for each term
*
* @param $term
* @param $taxonomy
*/
public function setup_term_urls( $term, $taxonomy ) {
$term_link = get_term_link( $term, $taxonomy );
if ( ! is_wp_error( $term_link ) ) {
$this->links[] = $term_link;
}
foreach ( $this->feeds as $feed ) {
$term_link_feed = get_term_feed_link( $term, $taxonomy, $feed );
if ( $term_link_feed ) {
$this->links[] = $term_link_feed;
}
}
$taxonomy_object = get_taxonomy( $taxonomy );
if ( $taxonomy_object->show_in_rest && $taxonomy_object->rest_base ) {
$base = $taxonomy_object->rest_base;
$this->links[] = get_rest_url( null, '/wp/v2/' . $base );
$this->links[] = get_rest_url( null, '/wp/v2/' . $base . '/'. $term );
}
}
/**
* Home page / blog page and feed links
*/
public function setup_site_urls() {
if ( get_option( 'show_on_front' ) == 'page' ) {
$this->links[] = get_permalink( get_option( 'page_for_posts' ) );
}
$this->links[] = home_url( '/' );
foreach ( $this->feeds as $feed ) {
$this->links[] = get_feed_link( $feed );
}
}
/**
* Get permalink, date archives and custom post type links
*
* @param $post
*/
public function setup_post_urls( $post ) {
$post = get_post( $post );
$this->links[] = get_permalink( $post );
if ( $post->post_type == 'post' ) {
$year = get_the_time( "Y", $post );
$month = get_the_time( "m", $post );
$day = get_the_time( "d", $post );
$this->links[] = get_year_link( $year );
$this->links[] = get_month_link( $year, $month );
$this->links[] = get_day_link( $year, $month, $day );
} else if ( ! in_array( $post->post_type, get_post_types( array( 'public' => true ) ) ) ) {
if ( $archive_link = get_post_type_archive_link( $post->post_type ) ) {
$this->links[] = $archive_link;
}
foreach ( $this->feeds as $feed ) {
if ( $archive_link_feed = get_post_type_archive_feed_link( $post->post_type, $feed ) ) {
$this->links[] = $archive_link_feed;
}
}
}
$post_type = get_post_type_object( $post->post_type );
if ( $post_type->show_in_rest && $post_type->rest_base ) {
$base = $post_type->rest_base;
$this->links[] = get_rest_url( null, '/wp/v2/' . $base );
$this->links[] = get_rest_url( null, '/wp/v2/' . $base . '/'. $post->ID );
}
}
/**
* Author profile and feed links
*
* @param $author_id
*/
public function setup_author_urls( $author_id ) {
$this->links[] = get_author_posts_url( $author_id );
foreach ( $this->feeds as $feed ) {
$this->links[] = get_author_feed_link( $author_id, $feed );
}
$this->links[] = get_rest_url( null, '/wp/v2/users' );
$this->links[] = get_rest_url( null, '/wp/v2/users/' . $author_id );
}
/**
* Get feed urls for comments for single posts
*
* @param $post_id
*/
public function setup_post_comment_urls( $post_id, $comment_id = 0 ) {
foreach ( $this->feeds as $feed ) {
$this->links[] = get_post_comments_feed_link( $post_id, $feed );
}
foreach ( $this->feeds as $feed ) {
$this->links[] = get_feed_link( "comments_" . $feed );
}
$this->links[] = get_rest_url( null, '/wp/v2/comments' );
$this->links[] = get_rest_url( null, '/wp/v2/comments/' . $comment_id );
}
/**
* Work around for those using Domain mapping or have CMS on different url.
*
* @param $links
*/
public function add_site_alias( $links ) {
$home = parse_url( home_url(), PHP_URL_HOST );
$compare_urls = array(
parse_url( get_option( 'home' ), PHP_URL_HOST ),
parse_url( get_option( 'siteurl' ), PHP_URL_HOST ),
parse_url( site_url(), PHP_URL_HOST )
);
// Compare home, site urls with filtered home url
foreach ( $compare_urls as $compare_url ) {
if ( $compare_url != $home ) {
foreach ( $links as $url ) {
$links[] = str_replace( $home, $compare_url, $url );
}
}
}
return $links;
}
/**
* Loop around all urls and clear
*/
public function clear_urls() {
if ( empty ( $this->get_links() ) ) {
return;
}
foreach ( $this->get_links() as $url ) {
self::clear_url( $url );
}
// Clear out links
$this->links = array();
// --- START OF MODIFIED CODE ---
// Set the default timezone to UTC before calling date()
$timezone_backup = date_default_timezone_get();
date_default_timezone_set('UTC');
// Update the timestamp option with the specified format
$batcache_flush_time = date('jS F Y g:ia') . "\nUTC";
update_option( 'flush-object-cache-for-single-page-time-stamp', $batcache_flush_time );
// Restore the original timezone
date_default_timezone_set($timezone_backup);
// --- END OF MODIFIED CODE ---
}
/**
*
* @param $url
*
* @return bool|false|int
*/
public static function clear_url( $url ) {
global $batcache, $wp_object_cache;
$url = apply_filters( 'batcache_manager_link', $url );
if ( empty( $url ) ) {
return false;
}
do_action( 'batcache_manager_before_flush', $url );
// Force to http
$url = set_url_scheme( $url, 'http' );
$url_key = md5( $url );
wp_cache_add( "{$url_key}_version", 0, $batcache->group );
$retval = wp_cache_incr( "{$url_key}_version", 1, $batcache->group );
// $batcache_no_remote_group_key = array_search( $batcache->group, (array) $wp_object_cache->no_remote_groups );
$batcache_no_remote_group_key = property_exists($wp_object_cache, 'no_remote_groups') ? array_search( $batcache->group, (array) $wp_object_cache->no_remote_groups ) : false;
if ( false !== $batcache_no_remote_group_key ) {
// The *_version key needs to be replicated remotely, otherwise invalidation won't work.
// The race condition here should be acceptable.
unset( $wp_object_cache->no_remote_groups[ $batcache_no_remote_group_key ] );
$retval = wp_cache_set( "{$url_key}_version", $retval, $batcache->group );
$wp_object_cache->no_remote_groups[ $batcache_no_remote_group_key ] = $batcache->group;
}
do_action( 'batcache_manager_after_flush', $url, $retval );
return $retval;
}
/**
* Filter links
*
* @return array
*/
public function get_links() {
$this->links = apply_filters( 'batcache_manager_links', $this->links );
return array_unique( $this->links );
}
}
global $batcache_manager;
$batcache_manager = Batcache_Manager::get_instance();
@@ -0,0 +1,64 @@
<?php // Pressable Cache Management mu-plugins index
// disable direct file access
if (!defined('ABSPATH'))
{
exit;
}
/*****
* This file references the Pressable Cache Management mu-plugins
* https://wordpress.org/documentation/article/must-use-plugins/
******/
if(file_exists(WPMU_PLUGIN_DIR.'/pressable-cache-management/pcm_extend_batcache.php')) {
require WPMU_PLUGIN_DIR.'/pressable-cache-management/pcm_extend_batcache.php';
}
if(file_exists(WPMU_PLUGIN_DIR.'/pressable-cache-management/cdn_exclude_specific_file.php')) {
require WPMU_PLUGIN_DIR.'/pressable-cache-management/cdn_exclude_specific_file.php';
}
if(file_exists(WPMU_PLUGIN_DIR.'/pressable-cache-management/pcm_cdn_extender.php')) {
require WPMU_PLUGIN_DIR.'/pressable-cache-management/pcm_cdn_extender.php';
}
if(file_exists(WPMU_PLUGIN_DIR.'/pressable-cache-management/cdn_exclude_jpg_png_webp.php')) {
require WPMU_PLUGIN_DIR.'/pressable-cache-management/cdn_exclude_jpg_png_webp.php';
}
if(file_exists(WPMU_PLUGIN_DIR.'/pressable-cache-management/cdn_exclude_css.php')) {
require WPMU_PLUGIN_DIR.'/pressable-cache-management/cdn_exclude_css.php';
}
if(file_exists(WPMU_PLUGIN_DIR.'/pressable-cache-management/cdn_exclude_js_json.php')) {
require WPMU_PLUGIN_DIR.'/pressable-cache-management/cdn_exclude_js_json.php';
}
if(file_exists(WPMU_PLUGIN_DIR.'/pressable-cache-management/pcm_exclude_font_files_from_cdn.php')) {
require WPMU_PLUGIN_DIR.'/pressable-cache-management/pcm_exclude_font_files_from_cdn.php';
}
// if(file_exists(WPMU_PLUGIN_DIR.'/pressable-cache-management/batcache_manager.php')) {
// require WPMU_PLUGIN_DIR.'/pressable-cache-management/pcm_batcache_manager.php.php';
// }
if(file_exists(WPMU_PLUGIN_DIR.'/pressable-cache-management/pcm_cache_wpp_cookies_pages.php')) {
require WPMU_PLUGIN_DIR.'/pressable-cache-management/pcm_cache_wpp_cookies_pages.php';
}
if(file_exists(WPMU_PLUGIN_DIR.'/pressable-cache-management/pcm_exclude_query_string_gclid.php')) {
require WPMU_PLUGIN_DIR.'/pressable-cache-management/pcm_exclude_query_string_gclid.php';
}
if(file_exists(WPMU_PLUGIN_DIR.'/pressable-cache-management/pcm_exclude_pages_from_batcache.php')) {
require WPMU_PLUGIN_DIR.'/pressable-cache-management/pcm_exclude_pages_from_batcache.php';
}
@@ -0,0 +1,122 @@
<?php
/**
* Pressable Edge Cache Purge Functionality
* Mirrors the official repo's purge-edge-cache.php exactly,
* with branded admin notices applied.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
if ( isset( $_POST['purge_edge_cache_nonce'] ) ) {
if ( ! function_exists( 'pcm_pressable_edge_cache_purge_local' ) ) {
function pcm_pressable_edge_cache_purge_local() {
// 1. Verify nonce + capability
if (
! isset( $_POST['purge_edge_cache_nonce'] ) ||
! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['purge_edge_cache_nonce'] ) ), 'purge_edge_cache_nonce' ) ||
! current_user_can( 'manage_options' )
) {
return;
}
// 2. Ensure Edge Cache Plugin exists
if ( ! class_exists( 'Edge_Cache_Plugin' ) ) {
add_action( 'admin_notices', function() {
if ( function_exists( 'pcm_branded_notice' ) ) {
pcm_branded_notice( esc_html__( 'Error: Edge Cache Plugin is not active.', 'pressable_cache_management' ), '#dd3a03' );
} else {
printf( '<div class="notice notice-error is-dismissible"><p>%s</p></div>', esc_html__( 'Error: Edge Cache Plugin is not active.', 'pressable_cache_management' ) );
}
});
return;
}
// 3. Get Edge Cache instance and current status
$edge_cache = Edge_Cache_Plugin::get_instance();
$status_method = method_exists( $edge_cache, 'get_ec_status' ) ? 'get_ec_status' : null;
$enable_method = method_exists( $edge_cache, 'enable_ec' ) ? 'enable_ec' : null;
$server_status = $status_method ? $edge_cache->$status_method() : null;
$auto_enabled = false;
// 4. If disabled, handle based on availability of enable_ec()
if ( Edge_Cache_Plugin::EC_DISABLED === $server_status ) {
if ( null !== $enable_method ) {
$enabled = $edge_cache->$enable_method();
if ( $enabled ) {
$auto_enabled = true;
sleep( 2 );
} else {
add_action( 'admin_notices', function() {
if ( function_exists( 'pcm_branded_notice' ) ) {
pcm_branded_notice( esc_html__( 'Edge Cache was disabled and could not be auto-enabled. Purge aborted.', 'pressable_cache_management' ), '#dd3a03' );
} else {
printf( '<div class="notice notice-error is-dismissible"><p>%s</p></div>', esc_html__( 'Edge Cache was disabled and could not be auto-enabled. Purge aborted.', 'pressable_cache_management' ) );
}
});
return;
}
} else {
add_action( 'admin_notices', function() {
if ( function_exists( 'pcm_branded_notice' ) ) {
pcm_branded_notice( esc_html__( 'Edge Cache is disabled on the server. Enable Edge Cache.', 'pressable_cache_management' ), '#f59e0b' );
} else {
printf( '<div class="notice notice-warning is-dismissible"><p>%s</p></div>', esc_html__( 'Edge Cache is disabled on the server. Enable Edge Cache.', 'pressable_cache_management' ) );
}
});
return;
}
}
// 5. Purge domain cache
$result = method_exists( $edge_cache, 'purge_domain_now' )
? $edge_cache->purge_domain_now( 'dashboard-auto-purge' )
: false;
if ( $result ) {
update_option( 'edge-cache-purge-time-stamp', gmdate( 'jS F Y g:ia' ) . ' UTC' );
// Clear the Batcache status transient so the badge re-probes immediately.
// Without this the badge can sit on 'active' for up to 90s after a purge
// even though Batcache is now in a transitional broken state.
do_action( 'pcm_after_edge_cache_purge' );
$message = $auto_enabled
? esc_html__( 'Edge Cache was disabled on the server. It has been automatically enabled and purged successfully.', 'pressable_cache_management' )
: esc_html__( 'Edge Cache purged successfully.', 'pressable_cache_management' );
add_action( 'admin_notices', function() use ( $message ) {
if ( function_exists( 'pcm_branded_notice' ) ) {
pcm_branded_notice( $message, '#03fcc2' );
} else {
printf( '<div class="notice notice-success is-dismissible"><p>%s</p></div>', esc_html( $message ) );
}
});
} else {
add_action( 'admin_notices', function() {
if ( function_exists( 'pcm_branded_notice' ) ) {
pcm_branded_notice( esc_html__( 'Edge Cache purge failed. Please try again.', 'pressable_cache_management' ), '#dd3a03' );
} else {
printf( '<div class="notice notice-error is-dismissible"><p>%s</p></div>', esc_html__( 'Edge Cache purge failed. Please try again.', 'pressable_cache_management' ) );
}
});
}
}
add_action( 'init', 'pcm_pressable_edge_cache_purge_local' );
}
}
// Prevent duplicate section callback declarations
if ( ! function_exists( 'pressable_cache_management_callback_section_edge_cache' ) ) {
function pressable_cache_management_callback_section_edge_cache() {
echo '<p>' . esc_html__( 'These settings enable you to manage Edge Cache.', 'pressable_cache_management' ) . '</p>';
}
}
if ( ! function_exists( 'pressable_cache_management_callback_section_cache' ) ) {
function pressable_cache_management_callback_section_cache() {
echo '<p>' . esc_html__( 'These settings enable you to manage the object cache.', 'pressable_cache_management' ) . '</p>';
}
}
@@ -0,0 +1,63 @@
<?php //Pressable Cache Management - Custom function to turn on/off Pressable branding
/******************************
* Show branding Option
*******************************/
$pressable_branding = false;
$hide_pressable_branding_tab_options = get_option('remove_pressable_branding_tab_options');
//Check if options are set before processing
if (isset($hide_pressable_branding_tab_options['branding_on_off_radio_button']) && !empty($hide_pressable_branding_tab_options['branding_on_off_radio_button']))
{
$hide_pressable_branding_tab_options = sanitize_text_field($hide_pressable_branding_tab_options['branding_on_off_radio_button']);
}
//Set radion button state to defualt
if ('enable' === $hide_pressable_branding_tab_options)
{
$hide_pressable_branding_tab_options = get_option('remove_pressable_branding_tab_options');
// echo 'Show Branding';
//run your functions here if radio button is enabled
}
/******************************
* Hide branding Option
*******************************/
else
{
$pressable_branding = false;
$pressable_branding = get_option('remove_pressable_branding_tab_options');
//Check if options are set before processing
if (isset($hide_pressable_branding_tab_options['branding_on_off_radio_button']) && !empty($hide_pressable_branding_tab_options['branding_on_off_radio_button']))
{
$hide_pressable_branding_tab_options = sanitize_text_field($hide_pressable_branding_tab_options['branding_on_off_radio_button']);
}
//Set radio button state to defualt
if ('disable' === $hide_pressable_branding_tab_options)
{
$hide_pressable_branding_tab_options = get_option('remove_pressable_branding_tab_options');
// echo 'Hide Branding';
//run your functions here if radio button is disbaled
}
}
@@ -0,0 +1,146 @@
<?php
/**
* Pressable Cache Management - Turn On/Off Edge Cache
* Based directly on the official repo's turn-on-off-edge-cache.php
* with branded admin notices applied.
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
// ─── Shared branded notice helper (defined once here) ──────────────────────
if ( ! function_exists( 'pcm_branded_notice' ) ) {
function pcm_branded_notice( $message, $border_color = '#03fcc2', $is_html = false ) {
$id = 'pcm-notice-' . substr( md5( $message . $border_color . microtime() ), 0, 8 );
$wrap = 'display:inline-flex;align-items:flex-start;justify-content:space-between;gap:16px;'
. 'border-left:4px solid ' . esc_attr( $border_color ) . ';background:#fff;'
. 'border-radius:0 8px 8px 0;padding:14px 18px;'
. 'box-shadow:0 2px 8px rgba(4,0,36,.07);margin:10px 20px 10px 0;font-family:sans-serif;'
. 'min-width:260px;max-width:520px;';
$btn = 'background:none;border:none;cursor:pointer;color:#94a3b8;font-size:18px;'
. 'line-height:1;padding:0;flex-shrink:0;margin-top:2px;';
echo '<div id="' . esc_attr( $id ) . '" style="' . $wrap . '">';
echo '<div style="flex:1;">';
if ( $is_html ) {
echo $message; // caller already escaped
} else {
echo '<p style="margin:0;font-size:13px;color:#040024;">' . esc_html( $message ) . '</p>';
}
echo '</div>';
echo '<button type="button" onclick="document.getElementById(\'' . esc_js( $id ) . '\').remove();" style="' . $btn . '">&#x2297;</button>';
echo '</div>';
}
}
// ─── Notice: Edge Cache Enabled ─────────────────────────────────────────────
if ( ! function_exists( 'pressable_edge_cache_notice_success_enable' ) ) {
function pressable_edge_cache_notice_success_enable() {
$screen = get_current_screen();
if ( isset( $screen ) && 'toplevel_page_pressable_cache_management' !== $screen->id ) return;
$html = '<h3 style="margin:0 0 8px;font-size:14px;font-weight:700;color:#040024;">'
. '&#x1F389; ' . esc_html__( 'Edge Cache Enabled!', 'pressable_cache_management' ) . '</h3>';
$html .= '<p style="margin:0 0 6px;font-size:13px;color:#475569;">'
. esc_html__( 'Edge Cache provides performance improvements, particularly for Time to First Byte (TTFB), by serving page cache from the nearest server to your website visitors.', 'pressable_cache_management' )
. '</p>';
$html .= '<a href="https://pressable.com/knowledgebase/edge-cache/" target="_blank" '
. 'rel="noopener noreferrer" style="font-size:13px;color:#dd3a03;font-weight:600;text-decoration:none;">'
. esc_html__( 'Learn more about Edge Cache.', 'pressable_cache_management' ) . '</a>';
$nid = 'pcm-ec-enabled-' . substr( md5( microtime() ), 0, 8 );
$wrap = 'display:flex;align-items:flex-start;justify-content:space-between;gap:16px;'
. 'border-left:4px solid #03fcc2;background:#fff;'
. 'border-radius:0 8px 8px 0;padding:14px 18px;'
. 'box-shadow:0 2px 8px rgba(4,0,36,.07);margin:10px 0;font-family:sans-serif;';
$btn = 'background:none;border:none;cursor:pointer;color:#94a3b8;font-size:18px;'
. 'line-height:1;padding:0;flex-shrink:0;margin-top:2px;';
echo '<div style="max-width:920px;margin:0 20px;">';
echo '<div id="' . esc_attr( $nid ) . '" style="' . $wrap . '">';
echo '<div style="flex:1;">' . $html . '</div>';
echo '<button type="button" onclick="document.getElementById(\'' . esc_js( $nid ) . '\').remove();" style="' . $btn . '">&#x2297;</button>';
echo '</div>';
echo '</div>';
}
}
// ─── Notice: Edge Cache Disabled ────────────────────────────────────────────
if ( ! function_exists( 'pressable_edge_cache_notice_success_disable' ) ) {
function pressable_edge_cache_notice_success_disable() {
$screen = get_current_screen();
if ( isset( $screen ) && 'toplevel_page_pressable_cache_management' !== $screen->id ) return;
pcm_branded_notice( esc_html__( 'Edge Cache Deactivated.', 'pressable_cache_management' ), '#03fcc2' );
}
}
// ─── Notice: Error ───────────────────────────────────────────────────────────
if ( ! function_exists( 'pcm_pressable_edge_cache_error_msg' ) ) {
function pcm_pressable_edge_cache_error_msg( $error_message = '' ) {
$screen = get_current_screen();
if ( isset( $screen ) && 'toplevel_page_pressable_cache_management' !== $screen->id ) return;
$msg = empty( $error_message )
? esc_html__( 'Something went wrong trying to communicate with the Edge Cache system. Try again.', 'pressable_cache_management' )
: esc_html( $error_message );
pcm_branded_notice( $msg, '#dd3a03' );
}
}
// ─── Enable Edge Cache (mirrors repo exactly, adds branded notices) ─────────
function pcm_pressable_enable_edge_cache() {
if ( isset( $_POST['enable_edge_cache_nonce'] ) &&
wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['enable_edge_cache_nonce'] ) ), 'enable_edge_cache_nonce' ) ) {
if ( class_exists( 'Edge_Cache_Plugin' ) ) {
$edge_cache = Edge_Cache_Plugin::get_instance();
$result = $edge_cache->query_ec_backend( 'on', array( 'wp_action' => 'manual_dashboard_set' ) );
if ( is_wp_error( $result ) ) {
update_option( 'edge-cache-status', 'Error' );
update_option( 'edge-cache-enabled', 'disabled' );
add_action( 'admin_notices', function() use ( $result ) {
pcm_pressable_edge_cache_error_msg( $result->get_error_message() );
});
} else {
update_option( 'edge-cache-status', 'Success' );
update_option( 'edge-cache-enabled', 'enabled' );
delete_transient( 'pcm_ec_status_cache' ); // force fresh status on next page load
add_action( 'admin_notices', 'pressable_edge_cache_notice_success_enable' );
}
} else {
add_action( 'admin_notices', function() {
pcm_pressable_edge_cache_error_msg( 'Required Edge Cache dependency is not available.' );
});
}
}
}
add_action( 'init', 'pcm_pressable_enable_edge_cache' );
// ─── Disable Edge Cache (mirrors repo exactly, adds branded notices) ────────
function pcm_pressable_disable_edge_cache() {
if ( isset( $_POST['disable_edge_cache_nonce'] ) &&
wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['disable_edge_cache_nonce'] ) ), 'disable_edge_cache_nonce' ) ) {
if ( class_exists( 'Edge_Cache_Plugin' ) ) {
$edge_cache = Edge_Cache_Plugin::get_instance();
$result = $edge_cache->query_ec_backend( 'off', array( 'wp_action' => 'manual_dashboard_set' ) );
if ( is_wp_error( $result ) ) {
update_option( 'edge-cache-status', 'Error' );
update_option( 'edge-cache-enabled', 'enabled' ); // stays enabled on failure
add_action( 'admin_notices', function() use ( $result ) {
pcm_pressable_edge_cache_error_msg( $result->get_error_message() );
});
} else {
update_option( 'edge-cache-status', 'Success' );
update_option( 'edge-cache-enabled', 'disabled' );
delete_transient( 'pcm_ec_status_cache' ); // force fresh status on next page load
add_action( 'admin_notices', 'pressable_edge_cache_notice_success_disable' );
}
} else {
add_action( 'admin_notices', function() {
pcm_pressable_edge_cache_error_msg( 'Required Edge Cache dependency is not available.' );
});
}
}
}
add_action( 'init', 'pcm_pressable_disable_edge_cache' );
@@ -0,0 +1,181 @@
<?php
function pressable_cache_extend()
{
}
// http://www.php.net/is_writable
function is_writeable_wp_config($path)
{
if ((defined('PHP_OS_FAMILY') && 'Windows' !== constant('PHP_OS_FAMILY')) || stristr(PHP_OS, 'DAR') || !stristr(PHP_OS, 'WIN'))
{
return is_writeable($path);
}
// PHP's is_writable does not work with Win32 NTFS
if ($path[strlen($path) - 1] == '/')
{ // recursively return a temporary file path
return is_writeable_wp_config($path . uniqid(mt_rand()) . '.tmp');
}
elseif (is_dir($path))
{
return is_writeable_wp_config($path . '/' . uniqid(mt_rand()) . '.tmp');
}
// check tmp file for read/write capabilities
$rm = file_exists($path);
$f = @fopen($path, 'a');
if ($f === false) return false;
fclose($f);
if (!$rm)
{
unlink($path);
}
return true;
}
// function wp_cache_setting( $field, $value ) {
// global $wp_cache_config_file;
// $GLOBALS[ $field ] = $value;
// if ( is_numeric( $value ) ) {
// return wp_config_file_replace_line( '^ *\$' . $field, "\$$field = $value;", $wp_cache_config_file );
// } elseif ( is_bool( $value ) ) {
// $output_value = $value === true ? 'true' : 'false';
// return wp_config_file_replace_line( '^ *\$' . $field, "\$$field = $output_value;", $wp_cache_config_file );
// } elseif ( is_object( $value ) || is_array( $value ) ) {
// $text = var_export( $value, true );
// $text = preg_replace( '/[\s]+/', ' ', $text );
// return wp_config_file_replace_line( '^ *\$' . $field, "\$$field = $text;", $wp_cache_config_file );
// } else {
// return wp_config_file_replace_line( '^ *\$' . $field, "\$$field = '$value';", $wp_cache_config_file );
// }
// }
function wp_config_file_replace_line($old, $new, $my_file)
{
if (@is_file($my_file) == false)
{
if (function_exists('set_transient'))
{
set_transient('wpsc_config_error', 'config_file_missing', 10);
}
return false;
}
if (!is_writeable_wp_config($my_file))
{
if (function_exists('set_transient'))
{
set_transient('wpsc_config_error', 'config_file_ro', 10);
}
trigger_error("Error: file $my_file is not writable.");
return false;
}
$found = false;
$loaded = false;
$c = 0;
$lines = array();
while (!$loaded)
{
$lines = file($my_file);
if (!empty($lines) && is_array($lines))
{
$loaded = true;
}
else
{
$c++;
if ($c > 100)
{
if (function_exists('set_transient'))
{
set_transient('wpsc_config_error', 'config_file_not_loaded', 10);
}
trigger_error("wp_config_file_replace_line: Error - file $my_file could not be loaded.");
return false;
}
}
}
foreach ((array)$lines as $line)
{
if (trim($new) != '' && trim($new) == trim($line))
{
pressable_cache_extend("wp_config_file_replace_line: setting not changed - $new");
return true;
}
elseif (preg_match("/$old/", $line))
{
pressable_cache_extend("wp_config_file_replace_line: changing line " . trim($line) . " to *$new*");
$found = true;
}
}
global $cache_path;
$tmp_config_filename = tempnam($GLOBALS['cache_path'], 'wpsc');
rename($tmp_config_filename, $tmp_config_filename . ".php");
$tmp_config_filename .= ".php";
pressable_cache_extend('wp_config_file_replace_line: writing to ' . $tmp_config_filename);
$fd = fopen($tmp_config_filename, 'w');
if (!$fd)
{
if (function_exists('set_transient'))
{
set_transient('wpsc_config_error', 'config_file_ro', 10);
}
trigger_error("wp_config_file_replace_line: Error - could not write to $my_file");
return false;
}
if ($found)
{
foreach ((array)$lines as $line)
{
if (!preg_match("/$old/", $line))
{
fputs($fd, $line);
}
elseif ($new != '')
{
fputs($fd, "$new\n");
}
}
}
else
{
$done = false;
foreach ((array)$lines as $line)
{
// if ( $done || ! preg_match( '/\brequire_once\b/i', $line ) ) {
if ($done || !preg_match('/\b(require_once)\b/', $line))
{
fputs($fd, $line);
}
else
{
//add fputs($fd, "$new\n"); here to write function above require_once
fputs($fd, $line);
//Write function at the button of require_once
fputs($fd, "$new\n");
$done = true;
}
}
}
fclose($fd);
rename($tmp_config_filename, $my_file);
pressable_cache_extend('wp_config_file_replace_line: moved ' . $tmp_config_filename . ' to ' . $my_file);
// if (function_exists("opcache_invalidate"))
// {
// @opcache_invalidate($my_file);
// }
if (function_exists("wp_opcache_invalidate"))
{
wp_opcache_invalidate($my_file);
}
return true;
}