(Frederick, I’m submitting a bug report with this suggestion for you in case it’s useful.)
There is a problem in the core WP Object Caching functionality which also exists in W3TC Object Cache: if an object is cached, then switch_to_blog
is used and an object of the same ID is called then the object from the first site is used. Did I lose anyone? For example: You are in site 1 looking at post ID 10, you use switch_to_blog( 2 );
and use $id = 10; get_post( $id );
, the post from site 1 will be returned not the post from site 2.
As someone above pointed out, see https://core.trac.www.ads-software.com/ticket/14992
I’ve created a quick plugin to solve the issue and dropped it into my mu_plugins
folder.
Note: This plugin may cause posts from one site to be cached outside that site’s “awareness”, so WP will not immediately clear these “outside” caches if that post is amended/deleted. The object cache will still expire, so worst case scenario is a deleted/amended post hanging around in an “outside” cache for as long as you have set the expiration time for the W3TC Object Cache.
Please test that this plugin solves your problem and doesn’t create other issues for you before you deploy to a production webserver. ??
Plugin code:
<?php
/*
Plugin Name: <kbd>switch_to_blog</kbd> safe W3TC Object Cache
Plugin URI: https://simonwheatley.co.uk/wordpress/nswoc
Description: Amends the W3TC object cache keys so they are safe for use with extensive use of <code>switch_to_blog</code> and <code>restore_current_blog</code>. Also warns in admin area of erratic behaviour if W3TC Object Cache is NOT enabled.
Version: 0.2
*/
/* Copyright 2011 Simon Wheatley
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
/**
* Hooks the WP w3tc_objectcache_cache_key action
*
* @param string $key A W3TC Object Cache key
* @return string An altered W3TC Object Cache key
**/
function nswoc_w3tc_objectcache_cache_key( $key ) {
global $blog_id;
$key = (int) $blog_id . '-' . $key;
return $key;
}
w3tc_add_action( 'w3tc_objectcache_cache_key', 'nswoc_w3tc_objectcache_cache_key' );
/**
* Hooks the WP admin_notices action to warn admins if
* the W3TC Object Cache is not active.
*
* @return void
**/
function nswoc_admin_notices() {
if ( nswoc_is_w3tc_object_cache_active() )
return;
$url = admin_url( 'admin.php?page=w3tc_general' );
if ( current_user_can( 'manage_plugins' ) )
echo "<div class='error'><p>" . sprintf( __( 'Please <a href="%s">enable W3TC Object Caching</a> to avoid erratic behaviour within this website.', 'nswoc' ), $url ) . "</p></div>";
else
echo "<div class='error'><p>" . __( 'Please ask the website administrator to enable W3TC Object Caching to avoid erratic behaviour within this website.', 'nswoc' ) . "</p></div>";
}
add_action( 'admin_notices', 'nswoc_admin_notices' );
/**
* Is the W3TC Object Cache active.
*
* @return bool True if the W3TC Object Cache is active
**/
function nswoc_is_w3tc_object_cache_active() {
if ( ! defined( 'W3TC_LIB_W3_DIR' ) )
return false;
require_once W3TC_LIB_W3_DIR . '/Config.php';
$config = & W3_Config::instance();
return $config->get_boolean('objectcache.enabled');
}
?>