Skip to content

Instantly share code, notes, and snippets.

@jtsternberg
Last active July 26, 2021 14:03
Show Gist options
  • Save jtsternberg/03219ce49c882f20d862724e0e594c73 to your computer and use it in GitHub Desktop.
Save jtsternberg/03219ce49c882f20d862724e0e594c73 to your computer and use it in GitHub Desktop.
Flush cache on Flywheel Local VM
<?php
function handle_remote_cache_requests_for_local() {
global $_wp_using_ext_object_cache;
if (
empty( $_wp_using_ext_object_cache )
|| ! isset( $_REQUEST['check'], $_REQUEST['command'] )
|| ! function_exists( 'wp_cache_' . $_REQUEST['command'] )
|| str_replace( ABSPATH, '', __FILE__ ) !== $_REQUEST['check']
) {
return;
}
$func = 'wp_cache_' . $_REQUEST['command'];
$args = ! empty( $_REQUEST['args'] ) ? (array) $_REQUEST['args'] : array();
$result = call_user_func_array( $func, $args );
if ( false === $result ) {
$result = 'false';
} elseif ( true === $result ) {
$result = 'true';
}
error_log( __FUNCTION__ . ':' . __LINE__ .') $func: '. print_r( compact( 'func', 'args', 'result' ), true ) );
echo $result;
}
add_action( 'admin_post_nopriv_wpcli_cache_command', 'handle_remote_cache_requests_for_local' );
/**
* Attempts to determine which object cache is being used.
*
* Note that the guesses made by this function are based on the WP_Object_Cache classes
* that define the 3rd party object cache extension. Changes to those classes could render
* problems with this function's ability to determine which object cache is being used.
*/
function wp_cache_type_for_local() {
global $_wp_using_ext_object_cache, $wp_object_cache;
$message = 'Default';
if ( false === $_wp_using_ext_object_cache ) {
// Test for Memcached PECL extension memcached object cache (https://github.com/tollmanz/wordpress-memcached-backend)
if ( isset( $wp_object_cache->m ) && is_a( $wp_object_cache->m, 'Memcached' ) ) {
$message = 'Memcached';
// Test for Memcache PECL extension memcached object cache (http://wordpress.org/extend/plugins/memcached/)
} elseif ( isset( $wp_object_cache->mc ) ) {
$is_memcache = true;
foreach ( $wp_object_cache->mc as $bucket ) {
if ( ! is_a( $bucket, 'Memcache' ) )
$is_memcache = false;
}
if ( $is_memcache )
$message = 'Memcache';
// Test for Xcache object cache (http://plugins.svn.wordpress.org/xcache/trunk/object-cache.php)
} elseif ( is_a( $wp_object_cache, 'XCache_Object_Cache' ) ) {
$message = 'Xcache';
// Test for WinCache object cache (http://wordpress.org/extend/plugins/wincache-object-cache-backend/)
} elseif ( class_exists( 'WinCache_Object_Cache' ) ) {
$message = 'WinCache';
// Test for APC object cache (http://wordpress.org/extend/plugins/apc/)
} elseif ( class_exists( 'APC_Object_Cache' ) ) {
$message = 'APC';
// Test for Redis Object Cache (https://github.com/alleyinteractive/wp-redis)
} elseif ( isset( $wp_object_cache->redis ) && is_a( $wp_object_cache->redis, 'Redis' ) ) {
$message = 'Redis';
} else {
$message = 'Unknown';
}
}
return $message;
}
if ( class_exists( 'WP_CLI' ) && class_exists( 'Cache_Command' ) ) {
/**
* Manage the object cache.
*
* ## EXAMPLES
*
* wp cache set my_key my_value my_group 300
*
* wp cache get my_key my_group
*/
class Cache_Command_For_Flywheel_Local extends Cache_Command {
/**
* Add a value to the object cache.
*
* @synopsis <key> <value> [<group>] [<expiration>]
*/
public function add( $args, $assoc_args ) {
list( $key, $value ) = $args;
$group = isset( $args[2] ) ? $args[2] : '';
$expiration = isset( $args[3] ) ? $args[3] : 0;
$result = self::remote_command( 'add', array( $key, $value, $group, $expiration ) );
if ( ! $result ) {
WP_CLI::error( "Could not add object '$key' in group '$group'. Does it already exist?" );
}
WP_CLI::success( "Added object '$key' in group '$group'." );
}
/**
* Decrement a value in the object cache.
*
* @synopsis <key> [<offset>] [<group>]
*/
public function decr( $args, $assoc_args ) {
$key = $args[0];
$offset = isset( $args[1] ) ? $args[1] : 1;
$group = isset( $args[2] ) ? $args[2] : '';
$value = self::remote_command( 'decr', array( $key, $offset, $group ) );
if ( false === $value ) {
WP_CLI::error( 'The value was not decremented.' );
}
WP_CLI::print_value( $value, $assoc_args );
}
/**
* Remove a value from the object cache.
*
* @synopsis <key> [<group>]
*/
public function delete( $args, $assoc_args ) {
$key = $args[0];
$group = ( isset( $args[1] ) ) ? $args[1] : '';
$result = self::remote_command( 'delete', array( $key, $group ) );
if ( false === $result ) {
WP_CLI::error( 'The object was not deleted.' );
}
WP_CLI::success( 'Object deleted.' );
}
/**
* Flush the object cache.
*/
public function flush( $args, $assoc_args ) {
$result = self::remote_command( 'flush' );
if ( false === $result ) {
WP_CLI::error( 'The object cache could not be flushed.' );
}
WP_CLI::success( 'The cache was flushed.' );
}
/**
* Get a value from the object cache.
*
* @synopsis <key> [<group>]
*/
public function get( $args, $assoc_args ) {
$key = $args[0];
$group = ( isset( $args[1] ) ) ? $args[1] : '';
$value = self::remote_command( 'get', array( $key, $group ) );
if ( false === $value ) {
WP_CLI::error( "Object with key '$key' and group '$group' not found." );
}
WP_CLI::print_value( $value, $assoc_args );
}
/**
* Increment a value in the object cache.
*
* @synopsis <key> [<offset>] [<group>]
*/
public function incr( $args, $assoc_args ) {
$key = $args[0];
$offset = isset( $args[1] ) ? $args[1] : 1;
$group = isset( $args[2] ) ? $args[2] : '';
$value = self::remote_command( 'incr', array( $key, $offset, $group ) );
if ( false === $value ) {
WP_CLI::error( 'The value was not incremented.' );
}
WP_CLI::print_value( $value, $assoc_args );
}
/**
* Replace an existing value in the object cache.
*
* @synopsis <key> <value> [<group>] [<expiration>]
*/
public function replace( $args, $assoc_args ) {
list( $key, $value ) = $args;
$group = isset( $args[2] ) ? $args[2] : '';
$expiration = isset( $args[3] ) ? $args[3] : 0;
$result = self::remote_command( 'replace', array( $key, $value, $group, $expiration ) );
if ( false === $result ) {
WP_CLI::error( "Could not replace object '$key' in group '$group'. Does it already exist?" );
}
WP_CLI::success( "Replaced object '$key' in group '$group'." );
}
/**
* Set a value to the object cache.
*
* @synopsis <key> <value> [<group>] [<expiration>]
*/
public function set( $args, $assoc_args ) {
list( $key, $value ) = $args;
$group = isset( $args[2] ) ? $args[2] : '';
$expiration = isset( $args[3] ) ? $args[3] : 0;
$result = self::remote_command( 'set', array( $key, $value, $group, $expiration ) );
if ( false === $result ) {
WP_CLI::error( "Could not add object '$key' in group '$group'." );
}
WP_CLI::success( "Set object '$key' in group '$group'." );
}
/**
* Attempts to determine which object cache is being used.
*
* Note that the guesses made by this function are based on the WP_Object_Cache classes
* that define the 3rd party object cache extension. Changes to those classes could render
* problems with this function's ability to determine which object cache is being used.
*/
public function type( $args, $assoc_args ) {
$message = self::remote_command( 'type_for_local' );
WP_CLI::line( $message );
}
/**
* Flushes the Flywheel Local site cache by performing an http request.
*/
protected static function remote_command( $command, $args = array() ) {
$url = admin_url( 'admin-post.php?action=wpcli_cache_command' );
$check = str_replace( ABSPATH, '', __FILE__ );
$response = wp_remote_post( $url, array(
'body' => compact( 'command', 'args', 'check' ),
) );
$result = wp_remote_retrieve_body( $response );
if ( is_string( $result ) ) {
$lower = strtolower( $result );
if ( 'false' === $lower ) {
$result = false;
} elseif ( 'true' === $lower ) {
$result = true;
}
}
return $result;
}
}
add_action( 'plugins_loaded', function() {
// Stomp the standard cache command(s) with our own.
WP_CLI::add_command( 'cache', 'Cache_Command_For_Flywheel_Local' );
} );
}
@sirchrispy
Copy link

Thanks for sharing this code with the world! It's solved an issue that's been so frustrating: Local by Flywheel's cache duplicating plugins in the admin area. Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment