diff --git a/modules/ppcp-api-client/src/ApiModule.php b/modules/ppcp-api-client/src/ApiModule.php index 12cdd12a6..be55b951e 100644 --- a/modules/ppcp-api-client/src/ApiModule.php +++ b/modules/ppcp-api-client/src/ApiModule.php @@ -113,23 +113,16 @@ class ApiModule implements ServiceModule, ExtendingModule, ExecutableModule { 'woocommerce_paypal_payments_flush_api_cache', static function () use ( $c ) { $caches = array( - 'api.paypal-bearer-cache' => array( - PayPalBearer::CACHE_KEY, - ), - 'api.client-credentials-cache' => array( - SdkClientToken::CACHE_KEY, - ), + 'api.paypal-bearer-cache', + 'api.client-credentials-cache', + 'settings.service.signup-link-cache', ); - foreach ( $caches as $cache_id => $keys ) { + foreach ( $caches as $cache_id ) { $cache = $c->get( $cache_id ); assert( $cache instanceof Cache ); - foreach ( $keys as $key ) { - if ( $cache->has( $key ) ) { - $cache->delete( $key ); - } - } + $cache->flush(); } } ); diff --git a/modules/ppcp-api-client/src/Helper/Cache.php b/modules/ppcp-api-client/src/Helper/Cache.php index 3b831ea00..e77f78825 100644 --- a/modules/ppcp-api-client/src/Helper/Cache.php +++ b/modules/ppcp-api-client/src/Helper/Cache.php @@ -5,7 +5,7 @@ * @package WooCommerce\PayPalCommerce\ApiClient\Helper */ -declare( strict_types=1 ); +declare( strict_types = 1 ); namespace WooCommerce\PayPalCommerce\ApiClient\Helper; @@ -48,8 +48,9 @@ class Cache { * * @return bool */ - public function has( string $key ): bool { + public function has( string $key ) : bool { $value = $this->get( $key ); + return false !== $value; } @@ -58,20 +59,47 @@ class Cache { * * @param string $key The key. */ - public function delete( string $key ): void { + public function delete( string $key ) : void { delete_transient( $this->prefix . $key ); } /** * Caches a value. * - * @param string $key The key under which the value should be cached. - * @param mixed $value The value to cache. + * @param string $key The key under which the value should be cached. + * @param mixed $value The value to cache. * @param int $expiration Time until expiration in seconds. * * @return bool */ - public function set( string $key, $value, int $expiration = 0 ): bool { + public function set( string $key, $value, int $expiration = 0 ) : bool { return (bool) set_transient( $this->prefix . $key, $value, $expiration ); } + + /** + * Flushes all items of the current "cache group", i.e., items that use the defined prefix. + * + * @return void + */ + public function flush() : void { + global $wpdb; + + // Get a list of all transients with the relevant "group prefix" from the DB. + $transients = $wpdb->get_col( + $wpdb->prepare( + "SELECT option_name FROM $wpdb->options WHERE option_name LIKE %s", + $wpdb->esc_like( '_transient_' . $this->prefix ) . '%' + ) + ); + + /** + * Delete each cache item individually to ensure WP can fire all relevant + * actions, perform checks and other cleanup tasks and ensures eventually + * object cache systems, like Redis, are kept in-sync with the DB. + */ + foreach ( $transients as $transient ) { + $key = str_replace( '_transient_' . $this->prefix, '', $transient ); + $this->delete( $key ); + } + } }