Skip to content

Instantly share code, notes, and snippets.

@spacedmonkey
Last active August 29, 2015 14:25
Show Gist options
  • Save spacedmonkey/fcfe7ada50490fb857b0 to your computer and use it in GitHub Desktop.
Save spacedmonkey/fcfe7ada50490fb857b0 to your computer and use it in GitHub Desktop.
<?php
/*
Plugin Name: Advanced Nav Caching
Description: Cache nav output
Version: 1.0.0
Author: Spacedmonkey
*/
class Advanced_Nav_Cache {
var $CACHE_GROUP_PREFIX = 'advanced_nav_cache_';
// Flag for temp (within one page load) turning invalidations on and off
// @see dont_clear_advanced_nav_cache()
// @see do_clear_advanced_nav_cache()
// Used to prevent invalidation during new comment
var $do_flush_cache = true;
// Flag for preventing multiple invalidations in a row: clean_post_cache() calls itself recursively for post children.
var $need_to_flush_cache = true; // Currently disabled
/* Per cache-clear data */
var $cache_incr = 0; // Increments the cache group (advanced_nav_cache_0, advanced_nav_cache_1, ...)
var $cache_group = ''; // CACHE_GROUP_PREFIX . $cache_incr
// custom caching rules
var $cache_on_single;
var $cache_on_search;
function __construct() {
// Specific to certain Memcached Object Cache plugins
if ( function_exists( 'wp_cache_add_group_prefix_map' ) ) {
wp_cache_add_group_prefix_map( $this->CACHE_GROUP_PREFIX, 'advanced_nav_cache' );
}
defined( 'ANC_ENABLE_ON_SINGLE' ) or define( 'ANC_ENABLE_ON_SINGLE', true );
defined( 'ANC_ENABLE_ON_SEARCH' ) or define( 'ANC_ENABLE_ON_SEARCH', true );
$this->cache_on_single = ANC_ENABLE_ON_SINGLE;
$this->cache_on_search = ANC_ENABLE_ON_SEARCH;
$this->setup_for_blog();
add_action( 'switch_blog', array( $this, 'setup_for_blog' ), 10, 2 );
add_action( 'clean_term_cache', array( $this, 'clear_advanced_nav_cache' ) );
add_action( 'clean_post_cache', array( $this, 'clear_advanced_nav_cache' ) );
// Don't clear Advanced Post Cache for a new comment - temp core hack
// http://core.trac.wordpress.org/ticket/15565
add_action( 'wp_updating_comment_count', array( $this, 'dont_clear_advanced_nav_cache' ) );
add_action( 'wp_update_comment_count' , array( $this, 'do_clear_advanced_nav_cache' ) );
add_filter( 'pre_wp_nav_menu', array( $this, 'pre_wp_nav_menu' ), 9, 2 );
add_filter( 'wp_nav_menu', array( $this, 'wp_nav_menu' ), 99, 2 );
}
function setup_for_blog( $new_blog_id = false, $previous_blog_id = false ) {
if ( $new_blog_id && $new_blog_id == $previous_blog_id ) {
return;
}
$this->cache_incr = wp_cache_get( 'advanced_nav_cache', 'cache_incrementors' ); // Get and construct current cache group name
if ( !is_numeric( $this->cache_incr ) ) {
$now = time();
wp_cache_set( 'advanced_nav_cache', $now, 'cache_incrementors' );
$this->cache_incr = $now;
}
$this->cache_group = $this->CACHE_GROUP_PREFIX . $this->cache_incr;
}
public function pre_wp_nav_menu( $output, $args ) {
if( $this->isLoadFromCacheEnabled($args) ) {
$cached_value = wp_cache_get( $this->get_key( $args ), $this->cache_group );
if ( $cached_value !== false ) {
$output = $cached_value;
}
}
return $output;
}
public function wp_nav_menu( $output, $args ) {
if( $this->isLoadFromCacheEnabled($args) ) {
$cached_value = wp_cache_get( $this->get_key( $args ), $this->cache_group );
if ( $cached_value === false ) {
wp_cache_set( $this->get_key( $args ), $output, $this->cache_group );
}
}
return $output;
}
public function get_key( $args ) {
$object_id = $this->get_variabled();
$flat_args = md5( serialize( $args ) );
$cache_key = sprintf( '%s_%s', $object_id, $flat_args );
return $cache_key;
}
public function get_variabled(){
global $wp_query;
if( $wp_query->is_404() ){
$test = 'error_404';
}else{
$test = $wp_query->query_vars;
if($test['paged']){
$test['paged'] = 0;
}
asort($test);
$test = serialize($test);
}
$test = md5($test);
return $test;
}
public function clear_advanced_nav_cache() {
$this->flush_cache();
}
public function do_clear_advanced_nav_cache() {
$this->do_flush_cache = true;
}
public function dont_clear_advanced_nav_cache() {
$this->do_flush_cache = false;
}
/* Advanced Post Cache API */
/**
* Flushes the cache by incrementing the cache group
*/
public function flush_cache() {
// Cache flushes have been disabled
if ( !$this->do_flush_cache )
return;
// Bail on post preview
if ( is_admin() && isset( $_POST['wp-preview'] ) && 'dopreview' == $_POST['wp-preview'] )
return;
// Bail on autosave
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
// We already flushed once this page load, and have not put anything into the cache since.
// OTHER processes may have put something into the cache! In theory, this could cause stale caches.
// We do this since clean_post_cache() (which fires the action this method attaches to) is called RECURSIVELY for all descendants.
// if ( !$this->need_to_flush_cache )
// return;
$this->cache_incr = wp_cache_incr( 'advanced_nav_cache', 1, 'cache_incrementors' );
if ( 10 < strlen( $this->cache_incr ) ) {
wp_cache_set( 'advanced_nav_cache', 0, 'cache_incrementors' );
$this->cache_incr = 0;
}
$this->cache_group = $this->CACHE_GROUP_PREFIX . $this->cache_incr;
$this->need_to_flush_cache = false;
}
/**
*
* @return boolean
*/
public function isLoadFromCacheEnabled($args = array()) {
$enabled = true;
if ( is_admin() ) {
$enabled = false;
}
if ( is_feed() ) {
$enabled = false;
}
if ( is_preview() ) {
$enabled = false;
}
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) {
$enabled = false;
}
if ( defined( 'DOING_CRON' ) && DOING_CRON ) {
$enabled = false;
}
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ){
$enabled = false;
}
if ( is_search() ){
$enabled = $this->cache_on_search;
}
if ( is_singular() && ! is_front_page()){
$enabled = $this->cache_on_single;
}
return apply_filters('filter_name', $enabled, $args );
}
}
global $advanced_nav_cache_object;
$advanced_nav_cache_object = new Advanced_Nav_Cache();
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment