One of the best ways to ensure that a WordPress site–well any site really–stays performant and not broken is by leveraging caching.
WordPress by default doesn’t do much caching other than some in-memory caching of objects, and the odd database caching via the Transients API.
This site currently has three layers of caching:
- PHP OPcache
- WordPress Object Cache
- Full page caching
This means I have three different plugins that I have to manage with these caches:
So if I am doing some development and want to purge one or more caches, I need to go dig around three different places to purge these, and that’s not fun. To help combat this, I made myself a simple Admin Dashboard widget with quick access to purge each of these:
Here’s the code:
<?php
class Emrikol_Cache_Dashboard {
public static function instance() {
static $instance = false;
if ( ! $instance ) {
$instance = new Emrikol_Cache_Dashboard();
}
return $instance;
}
public function __construct() {
add_action( 'init', array( $this, 'init' ) );
}
public function init() {
if ( $this->is_admin() && isset( $_GET['ead_purge_object_cache'] ) && check_admin_referer( 'manual_purge' ) ) {
$did_flush = wp_cache_flush();
if ( $did_flush ) {
add_action( 'admin_notices', array( $this, 'message_object_cache_purge_success' ) );
} else {
add_action( 'admin_notices', array( $this, 'message_object_cache_purge_failure' ) );
}
} elseif ( $this->is_admin() && isset( $_GET['ead_purge_wp_super_cache'] ) && check_admin_referer( 'manual_purge' ) ) {
global $file_prefix;
wp_cache_clean_cache( $file_prefix, true );
add_action( 'admin_notices', array( $this, 'message_wp_super_cache_purge_success' ) );
} elseif ( $this->is_admin() && isset( $_GET['ead_purge_OPcache'] ) && check_admin_referer( 'manual_purge' ) ) {
// Taken from: https://wordpress.org/plugins/flush-opcache/
// Check if file cache is enabled and delete it if enabled.
// phpcs:ignore WordPress.VIP.FileSystemWritesDisallow.file_ops_is_writable
if ( ini_get( 'OPcache.file_cache' ) && is_writable( ini_get( 'OPcache.file_cache' ) ) ) {
$files = new RecursiveIteratorIterator( new RecursiveDirectoryIterator( ini_get( 'OPcache.file_cache' ), RecursiveDirectoryIterator::SKIP_DOTS ), RecursiveIteratorIterator::CHILD_FIRST );
foreach ( $files as $fileinfo ) {
$todo = ( $fileinfo->isDir() ? 'rmdir' : 'unlink' );
$todo( $fileinfo->getRealPath() );
}
}
// Flush OPcache.
$did_flush = OPcache_reset();
if ( $did_flush ) {
add_action( 'admin_notices', array( $this, 'message_OPcache_purge_success' ) );
} else {
add_action( 'admin_notices', array( $this, 'message_OPcache_purge_failure' ) );
}
}
add_action( 'wp_dashboard_setup', array( $this, 'add_dashboard_widgets' ) );
}
public function add_dashboard_widgets() {
if ( $this->is_admin() ) {
wp_add_dashboard_widget( 'emrikol_admin_dashboard', 'Cache Control', array( $this, 'show_admin_dashboard' ) );
}
}
public function show_admin_dashboard() {
if ( false === get_parent_class( $GLOBALS['wp_object_cache'] ) ) {
// Persistent Object Cache detected.
?>
<div class="activity-block">
<span class="button"><a href="<?php echo esc_url( wp_nonce_url( admin_url( '?ead_purge_object_cache' ), 'manual_purge' ) ); ?>"><strong>Purge Object Cache</strong></a></span>
<p>Force a purge of your entire site's object cache.</p>
</div>
<?php
} else {
// Transients!
?>
<div class="activity-block">
<h3>Transients</h3>
<p>Transients cannot currently be removed manually.</p>
</div>
<?php
}
if ( function_exists( 'wp_cache_clean_cache' ) ) {
// WP Super Cache!
?>
<div class="activity-block">
<span class="button"><a href="<?php echo esc_url( wp_nonce_url( admin_url( '?ead_purge_wp_super_cache' ), 'manual_purge' ) ); ?>"><strong>Purge Page Cache</strong></a></span>
<p>Force a purge of your entire site's page cache.</p>
</div>
<?php
}
if ( function_exists( 'OPcache_reset' ) ) {
// PHP OPcache.
?>
<div class="activity-block">
<span class="button"><a href="<?php echo esc_url( wp_nonce_url( admin_url( '?ead_purge_OPcache' ), 'manual_purge' ) ); ?>"><strong>Purge PHP OPcache</strong></a></span>
<p>Force a purge of your entire site's PHP OPcache.</p>
</div>
<?php
}
}
public function message_wp_super_cache_purge_success() {
echo '<div id="message" class="notice notice-success is-dismissible"><p>Page Cache purged!</p></div>';
}
public function message_object_cache_purge_success() {
echo '<div id="message" class="notice notice-success is-dismissible"><p>Object Cache purged!</p></div>';
}
public function message_object_cache_purge_failure() {
echo '<div id="message" class="notice notice-error is-dismissible"><p>Object Cache purge failed!</p></div>';
}
public function message_OPcache_purge_success() {
echo '<div id="message" class="notice notice-success is-dismissible"><p>PHP OPcache purged!</p></div>';
}
public function message_OPcache_purge_failure() {
echo '<div id="message" class="notice notice-error is-dismissible"><p>PHP OPcache purge failed!</p></div>';
}
private function is_admin() {
if ( current_user_can( 'manage_options' ) ) {
return true;
}
return false;
}
}
Emrikol_Cache_Dashboard::instance();
Code language: HTML, XML (xml)
Leave a Reply