300 lines
13 KiB
PHP
300 lines
13 KiB
PHP
<?php
|
|
/**
|
|
* Plugin Name: Cloudflare Cache Purger
|
|
* Plugin URI: https://git.optimull.com/lsemenenko/cloudflare-cache-purger
|
|
* Description: Automatically purges Cloudflare cache when specific WordPress hooks are fired.
|
|
* Version: 1.0.0
|
|
* Author: Leonid Semenenko
|
|
* Author URI: https://optimull.com
|
|
* License: GPL-2.0+
|
|
* License URI: http://www.gnu.org/licenses/gpl-2.0.txt
|
|
* Text Domain: cloudflare-cache-purger
|
|
*/
|
|
|
|
// Exit if accessed directly
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit;
|
|
}
|
|
|
|
class Cloudflare_Cache_Purger {
|
|
/**
|
|
* Cloudflare API credentials.
|
|
*/
|
|
private $api_token;
|
|
private $zone_id;
|
|
|
|
/**
|
|
* Debug mode flag.
|
|
*/
|
|
private $debug_mode;
|
|
|
|
/**
|
|
* Initialize the plugin.
|
|
*/
|
|
public function __construct() {
|
|
// Load settings.
|
|
$this->load_settings();
|
|
|
|
// Register hooks to purge cache.
|
|
$this->register_hooks();
|
|
|
|
// Add admin menu.
|
|
add_action( 'admin_menu', array( $this, 'add_admin_menu' ) );
|
|
add_action( 'admin_init', array( $this, 'register_settings' ) );
|
|
}
|
|
|
|
/**
|
|
* Load settings from WordPress options.
|
|
*/
|
|
private function load_settings() {
|
|
$this->api_token = get_option( 'cloudflare_cache_purger_api_token', '' );
|
|
$this->zone_id = get_option( 'cloudflare_cache_purger_zone_id', '' );
|
|
$this->debug_mode = get_option( 'cloudflare_cache_purger_debug', false );
|
|
}
|
|
|
|
/**
|
|
* Register hooks that will trigger cache purge.
|
|
*/
|
|
private function register_hooks() {
|
|
// Hooks specified in requirements.
|
|
add_action( 'pending_to_publish', array( $this, 'purge_cache' ) );
|
|
add_action( 'publish_to_trash', array( $this, 'purge_cache' ) );
|
|
add_action( 'future_to_publish', array( $this, 'purge_cache' ) );
|
|
add_action( 'draft_to_publish', array( $this, 'purge_cache' ) );
|
|
add_action( 'delete_attachment', array( $this, 'purge_cache' ) );
|
|
add_action( 'autoptimize_action_cachepurged', array( $this, 'purge_cache' ) );
|
|
add_action( 'switch_theme', array( $this, 'purge_cache' ) );
|
|
add_action( 'customize_save_after', array( $this, 'purge_cache' ) );
|
|
}
|
|
|
|
/**
|
|
* Write debug information to a log file in wp-content.
|
|
*
|
|
* @param string $message The debug message.
|
|
*/
|
|
private function debug_log( $message ) {
|
|
$log_file = WP_CONTENT_DIR . '/cloudflare-cache-purger-debug.log';
|
|
$formatted_message = '[' . date( 'Y-m-d H:i:s' ) . '] ' . $message . "\n";
|
|
file_put_contents( $log_file, $formatted_message, FILE_APPEND );
|
|
}
|
|
|
|
/**
|
|
* Purge the Cloudflare cache.
|
|
*/
|
|
public function purge_cache() {
|
|
// Check if credentials are set.
|
|
if ( empty( $this->api_token ) || empty( $this->zone_id ) ) {
|
|
error_log( 'Cloudflare Cache Purger: API credentials not set.' );
|
|
if ( $this->debug_mode ) {
|
|
$this->debug_log( 'API credentials not set.' );
|
|
}
|
|
return;
|
|
}
|
|
|
|
// Prepare request to Cloudflare API.
|
|
$url = "https://api.cloudflare.com/client/v4/zones/{$this->zone_id}/purge_cache";
|
|
$headers = array(
|
|
'Authorization: Bearer ' . $this->api_token,
|
|
'Content-Type: application/json'
|
|
);
|
|
|
|
// Purge everything.
|
|
$data = json_encode( array( 'purge_everything' => true ) );
|
|
|
|
// Log the purge event if debug is enabled.
|
|
if ( $this->debug_mode ) {
|
|
$this->debug_log( "Initiating cache purge. URL: $url, Data: $data" );
|
|
}
|
|
|
|
// Initialize cURL.
|
|
$ch = curl_init();
|
|
curl_setopt( $ch, CURLOPT_URL, $url );
|
|
curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, 'POST' );
|
|
curl_setopt( $ch, CURLOPT_HTTPHEADER, $headers );
|
|
curl_setopt( $ch, CURLOPT_POSTFIELDS, $data );
|
|
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
|
|
|
|
// Execute request.
|
|
$result = curl_exec( $ch );
|
|
$http_code = curl_getinfo( $ch, CURLINFO_HTTP_CODE );
|
|
|
|
// Close cURL.
|
|
curl_close( $ch );
|
|
|
|
// Log API response if debug is enabled.
|
|
if ( $this->debug_mode ) {
|
|
$this->debug_log( "API response: HTTP Code: $http_code, Result: $result" );
|
|
}
|
|
|
|
// Log result to error_log and show admin notices.
|
|
if ( $http_code >= 200 && $http_code < 300 ) {
|
|
error_log( 'Cloudflare Cache Purger: Cache successfully purged.' );
|
|
if ( is_admin() ) {
|
|
add_action( 'admin_notices', function() {
|
|
echo '<div class="notice notice-success is-dismissible"><p>Cloudflare cache has been purged successfully.</p></div>';
|
|
} );
|
|
}
|
|
} else {
|
|
error_log( 'Cloudflare Cache Purger: Failed to purge cache. Error: ' . $result );
|
|
if ( is_admin() ) {
|
|
add_action( 'admin_notices', function() use ( $result ) {
|
|
$error_message = json_decode( $result, true );
|
|
$message = isset( $error_message['errors'][0]['message'] ) ? $error_message['errors'][0]['message'] : 'Unknown error';
|
|
echo '<div class="notice notice-error is-dismissible"><p>Failed to purge Cloudflare cache: ' . esc_html( $message ) . '</p></div>';
|
|
} );
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Add admin menu.
|
|
*/
|
|
public function add_admin_menu() {
|
|
add_options_page(
|
|
'Cloudflare Cache Purger Settings',
|
|
'Cloudflare Cache',
|
|
'manage_options',
|
|
'cloudflare-cache-purger',
|
|
array( $this, 'settings_page' )
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Register plugin settings.
|
|
*/
|
|
public function register_settings() {
|
|
register_setting( 'cloudflare_cache_purger', 'cloudflare_cache_purger_api_token' );
|
|
register_setting( 'cloudflare_cache_purger', 'cloudflare_cache_purger_zone_id' );
|
|
register_setting( 'cloudflare_cache_purger', 'cloudflare_cache_purger_debug' );
|
|
|
|
add_settings_section(
|
|
'cloudflare_cache_purger_section',
|
|
'Cloudflare API Settings',
|
|
array( $this, 'settings_section_callback' ),
|
|
'cloudflare-cache-purger'
|
|
);
|
|
|
|
add_settings_field(
|
|
'cloudflare_cache_purger_api_token',
|
|
'Cloudflare API Token',
|
|
array( $this, 'api_token_field_callback' ),
|
|
'cloudflare-cache-purger',
|
|
'cloudflare_cache_purger_section'
|
|
);
|
|
|
|
add_settings_field(
|
|
'cloudflare_cache_purger_zone_id',
|
|
'Cloudflare Zone ID',
|
|
array( $this, 'zone_id_field_callback' ),
|
|
'cloudflare-cache-purger',
|
|
'cloudflare_cache_purger_section'
|
|
);
|
|
|
|
add_settings_field(
|
|
'cloudflare_cache_purger_debug',
|
|
'Enable Debug Logging',
|
|
array( $this, 'debug_field_callback' ),
|
|
'cloudflare-cache-purger',
|
|
'cloudflare_cache_purger_section'
|
|
);
|
|
}
|
|
|
|
/**
|
|
* Settings section description.
|
|
*/
|
|
public function settings_section_callback() {
|
|
echo '<p>Enter your Cloudflare API credentials to enable automatic cache purging.</p>';
|
|
echo '<p>You can find your Zone ID in the Cloudflare dashboard under "Overview" > "API" section.</p>';
|
|
echo '<p>Create an API token with the "Zone.Cache Purge" permission in the Cloudflare dashboard under "My Profile" > "API Tokens".</p>';
|
|
}
|
|
|
|
/**
|
|
* API token field callback.
|
|
*/
|
|
public function api_token_field_callback() {
|
|
$api_token = get_option( 'cloudflare_cache_purger_api_token', '' );
|
|
echo '<input type="password" id="cloudflare_cache_purger_api_token" name="cloudflare_cache_purger_api_token" value="' . esc_attr( $api_token ) . '" class="regular-text" />';
|
|
echo '<p class="description">Your Cloudflare API token. Create one with "Zone.Cache Purge" permission.</p>';
|
|
}
|
|
|
|
/**
|
|
* Zone ID field callback.
|
|
*/
|
|
public function zone_id_field_callback() {
|
|
$zone_id = get_option( 'cloudflare_cache_purger_zone_id', '' );
|
|
echo '<input type="text" id="cloudflare_cache_purger_zone_id" name="cloudflare_cache_purger_zone_id" value="' . esc_attr( $zone_id ) . '" class="regular-text" />';
|
|
echo '<p class="description">Your Cloudflare Zone ID for the domain.</p>';
|
|
}
|
|
|
|
/**
|
|
* Debug field callback.
|
|
*/
|
|
public function debug_field_callback() {
|
|
$debug = get_option( 'cloudflare_cache_purger_debug', false );
|
|
?>
|
|
<input type="checkbox" id="cloudflare_cache_purger_debug" name="cloudflare_cache_purger_debug" value="1" <?php checked( 1, $debug ); ?> />
|
|
<p class="description">Enable debug logging. Debug messages will be saved to <code>wp-content/cloudflare-cache-purger-debug.log</code>.</p>
|
|
<?php
|
|
}
|
|
|
|
/**
|
|
* Settings page content.
|
|
*/
|
|
public function settings_page() {
|
|
// Check user capabilities.
|
|
if ( ! current_user_can( 'manage_options' ) ) {
|
|
return;
|
|
}
|
|
?>
|
|
<div class="wrap">
|
|
<h1><?php echo esc_html( get_admin_page_title() ); ?></h1>
|
|
<form action="options.php" method="post">
|
|
<?php
|
|
settings_fields( 'cloudflare_cache_purger' );
|
|
do_settings_sections( 'cloudflare-cache-purger' );
|
|
submit_button( 'Save Settings' );
|
|
?>
|
|
</form>
|
|
|
|
<div class="card">
|
|
<h2>Manual Cache Purge</h2>
|
|
<p>Click the button below to manually purge the Cloudflare cache.</p>
|
|
<form method="post" action="">
|
|
<?php wp_nonce_field( 'manual_purge_action', 'manual_purge_nonce' ); ?>
|
|
<input type="hidden" name="action" value="manual_purge">
|
|
<input type="submit" class="button button-primary" value="Purge Cache">
|
|
</form>
|
|
</div>
|
|
|
|
<div class="card">
|
|
<h2>Automatic Purge Events</h2>
|
|
<p>This plugin automatically purges the Cloudflare cache when any of these WordPress events occur:</p>
|
|
<ul style="list-style-type: disc; margin-left: 20px;">
|
|
<li>When a post is edited</li>
|
|
<li>When a post is saved</li>
|
|
<li>When a post is deleted</li>
|
|
<li>When an attachment is deleted</li>
|
|
<li>When Autoptimize purges its cache</li>
|
|
<li>When a theme is switched</li>
|
|
<li>When customizer changes are saved</li>
|
|
</ul>
|
|
</div>
|
|
</div>
|
|
<?php
|
|
|
|
// Handle manual purge.
|
|
if (
|
|
isset( $_POST['action'] ) &&
|
|
$_POST['action'] === 'manual_purge' &&
|
|
isset( $_POST['manual_purge_nonce'] ) &&
|
|
wp_verify_nonce( $_POST['manual_purge_nonce'], 'manual_purge_action' )
|
|
) {
|
|
$this->purge_cache();
|
|
echo '<div class="notice notice-info is-dismissible"><p>Manual cache purge initiated.</p></div>';
|
|
}
|
|
}
|
|
}
|
|
|
|
// Initialize the plugin.
|
|
$cloudflare_cache_purger = new Cloudflare_Cache_Purger();
|