From 504df727809497f449bde1de770c7e9b925f02f4 Mon Sep 17 00:00:00 2001 From: Erick Hitter <ehitter@gmail.com> Date: Fri, 28 Feb 2014 00:43:43 -0800 Subject: [PATCH] Better Purging * Abstract Redis connection logic for reusability * Abstract purging logic for reusability * Create reusable purging logic * Introduce single-page purging via the admin bar See #5 --- redis-page-cache/redis-page-cache.php | 93 ++++++++++++++++++++++++--- 1 file changed, 83 insertions(+), 10 deletions(-) diff --git a/redis-page-cache/redis-page-cache.php b/redis-page-cache/redis-page-cache.php index 9b1ed07..fd22a02 100644 --- a/redis-page-cache/redis-page-cache.php +++ b/redis-page-cache/redis-page-cache.php @@ -55,9 +55,16 @@ class Redis_Page_Cache { * @return null */ private function __construct() { + // UI add_action( 'admin_init', array( $this, 'register_options' ) ); add_action( 'admin_menu', array( $this, 'register_ui' ) ); + + // Automated invalidations add_action( 'transition_post_status', array( $this, 'flush_cache' ), 10, 3 ); + + // Manual invalidations + add_action( 'admin_bar_menu', array( $this, 'admin_bar_menu' ), 999 ); + add_action( 'wp_ajax_redis_page_cache_purge', array( $this, 'ajax_purge' ) ); } /** @@ -114,6 +121,21 @@ class Redis_Page_Cache { return md5( 'v' . REDIS_PAGE_CACHE_CACHE_VERSION . '-' . $url ); } + /** + * Remove a specific URL from the Redis cache + * + * @param string $url + * @return null + */ + private function purge( $url ) { + $redis = $this->redis(); + + $redis_key = $this->build_key( $url ); + foreach ( array( '', 'M-', 'T-', ) as $prefix ) { + $redis->del( $prefix . $redis_key ); + } + } + /** * Register plugin's settings for proper sanitization * @@ -191,19 +213,70 @@ class Redis_Page_Cache { */ public function flush_cache( $new_status, $old_status, $post ) { if ( in_array( 'publish', array( $new_status, $old_status ) ) ) { - $redis = $this->redis(); + $this->purge( get_permalink( $post->ID ) ); + $this->purge( trailingslashit( get_home_url() ) ); + } + } - $redis_key = $this->build_key( get_permalink( $post->ID ) ); - foreach ( array( '', 'M-', 'T-', ) as $prefix ) { - $redis->del( $prefix . $redis_key ); - } + /** + * Add a purge option to the admin bar for those with proper capabilities + * + * @return null + */ + public function admin_bar_menu() { + global $wp_admin_bar; - //refresh the front page - $redis_key = $this->build_key( trailingslashit( get_home_url() ) ); - foreach ( array( '', 'M-', 'T-', ) as $prefix ) { - $redis->del( $prefix . $redis_key ); - } + // In the admin, only show on the post editor + if ( is_admin() && 'post' !== get_current_screen()->base ) { + return; + } + + // Only for Super Admins on multisite or Administrators on single site. + if ( ( is_multisite() && ! is_super_admin() ) || ! current_user_can( 'manage_options' ) ) { + return; + } + + // What are we trying to clear? + $page_url = set_url_scheme( esc_url( $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] ) ); + + $flush_url = add_query_arg( array( + 'action' => 'redis_page_cache_purge', + 'nonce' => wp_create_nonce( $page_url ), + 'url' => urlencode( $page_url ), + ), admin_url( 'admin-ajax.php' ) ); + + $wp_admin_bar->add_menu( array( + 'id' => 'redis-page-cache', + 'parent' => false, + 'title' => __( 'Clear Page Cache', 'redis-page-cache' ), + 'href' => $flush_url, + ) ); + } + + /** + * Purge a page from cache via an Ajax request + * + * @return null + */ + public function ajax_purge() { + $url = esc_url_raw( urldecode( $_GET['url'] ) ); + $redirect = add_query_arg( 'redis-page-cache-purge', 'failed', $url ); + + // Check nonce and referrer + if ( ! check_ajax_referer( $url, 'nonce', false ) ) { + wp_safe_redirect( $redirect, 302 ); } + + // Only for Super Admins on multisite or Administrators on single site. + if ( ( is_multisite() && ! is_super_admin() ) || ! current_user_can( 'manage_options' ) ) { + wp_safe_redirect( $redirect, 302 ); + } + + // Checks passed, so we purge and redirect with success noted in the query string + $this->purge( $url ); + + $redirect = add_query_arg( 'redis-page-cache-purge', 'success', $redirect ); + wp_safe_redirect( $redirect, 302 ); } } -- GitLab