• For one client, we have a requirement to statically cache two different templates (regular WP for desktop users and WP Touch Pro for mobile users) to prevent the site collapsing under load. For a while now I’ve had this running, but I’ve only just realised the caches weren’t being cleared properly. The following diff adds some supporting code and a new filter to WPSC which allows it to manage multiple static file caches… I hope it’s helpful to someone, and that this capability might find it’s way into the WPSC plugin.

    Index: wp-content/plugins/wp-super-cache/wp-cache-phase1.php
    ===================================================================
    --- wp-content/plugins/wp-super-cache/wp-cache-phase1.php	(revision 359498)
    +++ wp-content/plugins/wp-super-cache/wp-cache-phase1.php	(working copy)
    @@ -480,6 +480,53 @@
     	return $dir;
     }
    
    +function get_current_url_supercache_dirs( $post_id = 0 ) {
    +	global $cached_direct_pages, $cache_path, $wp_cache_request_uri;
    +
    +	$dirs = array();
    +
    +	if ( $post_id != 0 ) {
    +		$uri = str_replace( site_url(), '', get_permalink( $post_id ) );
    +	} else {
    +		$uri = $wp_cache_request_uri;
    +	}
    +	$uri = preg_replace('/[ <>\'\"\r\n\t\(\)]/', '', str_replace( '/index.php', '/', str_replace( '..', '', preg_replace("/(\?.*)?$/", '', $uri ) ) ) );
    +	$uri = str_replace( '\\', '', $uri );
    +	$default_dir = strtolower(preg_replace('/:.*$/', '',  $_SERVER["HTTP_HOST"])) . $uri; // To avoid XSS attacks
    +	$dirs[] = $default_dir;
    +	if ( function_exists( "apply_filters" ) )
    +		$dirs = apply_filters( 'supercache_dirs', $dirs, $default_dir );
    +	foreach ( $dirs as $i => & $dir ) {
    +		$dirs[ $i ] = $cache_path . 'supercache/' . $dirs[ $i ] . '/';
    +		if( is_array( $cached_direct_pages ) && in_array( $_SERVER[ 'REQUEST_URI' ], $cached_direct_pages ) ) {
    +			$dirs[ $i ] = ABSPATH . $uri . '/';
    +		}
    +		$dirs[ $i ] = str_replace( '//', '/', $dir );
    +		if ( isset( $GLOBALS[ 'wp_super_cache_debug' ] ) && $GLOBALS[ 'wp_super_cache_debug' ] ) wp_cache_debug( "supercache dir $i: " . $dirs[ $i ], 5 );
    +	}
    +	return $dirs;
    +}
    +
    +function get_base_supercache_dirs() {
    +	global $cached_direct_pages, $cache_path, $wp_cache_request_uri;
    +
    +	$dirs = array();
    +
    +	$default_dir = strtolower(preg_replace('/:.*$/', '',  $_SERVER["HTTP_HOST"]) ) . $uri; // To avoid XSS attacks
    +	$dirs[] = $default_dir;
    +	if ( function_exists( "apply_filters" ) )
    +		$dirs = apply_filters( 'supercache_dirs', $dirs, $default_dir );
    +	foreach ( $dirs as $i => & $dir ) {
    +		$dirs[ $i ] = $cache_path . 'supercache/' . $dirs[ $i ] . '/';
    +		if( is_array( $cached_direct_pages ) && in_array( $_SERVER[ 'REQUEST_URI' ], $cached_direct_pages ) ) {
    +			$dirs[ $i ] = ABSPATH . $uri . '/';
    +		}
    +		$dirs[ $i ] = str_replace( '//', '/', $dir );
    +		if ( isset( $GLOBALS[ 'wp_super_cache_debug' ] ) && $GLOBALS[ 'wp_super_cache_debug' ] ) wp_cache_debug( "supercache dir $i: " . $dirs[ $i ], 5 );
    +	}
    +	return $dirs;
    +}
    +
     function get_oc_version() {
     	$wp_cache_oc_key = wp_cache_get( "wp_cache_oc_key" );
     	if ( ! $wp_cache_oc_key ) {
    Index: wp-content/plugins/wp-super-cache/wp-cache-phase2.php
    ===================================================================
    --- wp-content/plugins/wp-super-cache/wp-cache-phase2.php	(revision 359498)
    +++ wp-content/plugins/wp-super-cache/wp-cache-phase2.php	(working copy)
    @@ -981,25 +981,28 @@
     	$permalink = trailingslashit( str_replace( get_option( 'siteurl' ), '', post_permalink( $post_id ) ) );
     	if( $super_cache_enabled ) {
     		$siteurl = trailingslashit( strtolower( preg_replace( '/:.*$/', '', str_replace( 'https://', '', get_option( 'home' ) ) ) ) );
    -		// make sure the front page has a rebuild file
    -		if ( $all == true ) {
    -			if ( isset( $GLOBALS[ 'wp_super_cache_debug' ] ) && $GLOBALS[ 'wp_super_cache_debug' ] ) wp_cache_debug( "Post change: deleting cache files in " . $cache_path . 'supercache/' . $siteurl, 4 );
    -			prune_super_cache( $cache_path . 'supercache/' . $siteurl . 'index.html', true, true );
    -			prune_super_cache( $cache_path . 'supercache/' . $siteurl . 'index.html.php', true, true );
    -			prune_super_cache( $cache_path . 'supercache/' . $siteurl . 'index.html.gz', true, true );
    -			do_action( 'gc_cache', 'prune', 'homepage' );
    +		$dirs = get_base_supercache_dirs();
    +		foreach ( $dirs as $dir ) {
    +			// make sure the front page has a rebuild file
    +			if ( $all == true ) {
    +				if ( isset( $GLOBALS[ 'wp_super_cache_debug' ] ) && $GLOBALS[ 'wp_super_cache_debug' ] ) wp_cache_debug( "Post change: deleting cache files in " . $cache_path . 'supercache/' . $siteurl, 4 );
    +				prune_super_cache( $dir . 'index.html', true, true );
    +				prune_super_cache( $dir . 'index.html.php', true, true );
    +				prune_super_cache( $dir . 'index.html.gz', true, true );
    +				do_action( 'gc_cache', 'prune', 'homepage' );
    +			}
    +			wp_cache_post_id_gc( $siteurl, $post_id );
    +			if( $all == true && get_option( 'show_on_front' ) == 'page' ) {
    +				if ( isset( $GLOBALS[ 'wp_super_cache_debug' ] ) && $GLOBALS[ 'wp_super_cache_debug' ] ) wp_cache_debug( "Post change: deleting page_on_front and page_for_posts pages.", 4 );
    +				if ( isset( $GLOBALS[ 'wp_super_cache_debug' ] ) && $GLOBALS[ 'wp_super_cache_debug' ] ) wp_cache_debug( "Post change: page_on_front " . get_option( 'page_on_front' ), 4 );
    +				wp_cache_post_id_gc( $siteurl, get_option( 'page_on_front' ), 'single' );
    +				$permalink = trailingslashit( str_replace( get_option( 'home' ), '', post_permalink( get_option( 'page_for_posts' ) ) ) );
    +				prune_super_cache( $dir . $permalink . 'index.html', true, true );
    +				prune_super_cache( $dir . $permalink . 'index.html.php', true, true );
    +				prune_super_cache( $dir . $permalink . 'index.html.gz', true, true );
    +				do_action( 'gc_cache', 'prune', $permalink );
    +			}
     		}
    -		wp_cache_post_id_gc( $siteurl, $post_id );
    -		if( $all == true && get_option( 'show_on_front' ) == 'page' ) {
    -			if ( isset( $GLOBALS[ 'wp_super_cache_debug' ] ) && $GLOBALS[ 'wp_super_cache_debug' ] ) wp_cache_debug( "Post change: deleting page_on_front and_page_for_posts pages.", 4 );
    -			if ( isset( $GLOBALS[ 'wp_super_cache_debug' ] ) && $GLOBALS[ 'wp_super_cache_debug' ] ) wp_cache_debug( "Post change: page_on_front " . get_option( 'page_on_front' ), 4 );
    -			wp_cache_post_id_gc( $siteurl, get_option( 'page_on_front' ), 'single' );
    -			$permalink = trailingslashit( str_replace( get_option( 'home' ), '', post_permalink( get_option( 'page_for_posts' ) ) ) );
    -			prune_super_cache( $cache_path . 'supercache/' . $siteurl . $permalink . 'index.html', true, true );
    -			prune_super_cache( $cache_path . 'supercache/' . $siteurl . $permalink . 'index.html.php', true, true );
    -			prune_super_cache( $cache_path . 'supercache/' . $siteurl . $permalink . 'index.html.gz', true, true );
    -			do_action( 'gc_cache', 'prune', $permalink );
    -		}
     	}
    
     	$matches = array();
    @@ -1021,9 +1024,11 @@
     						@unlink($meta_pathname);
     						@unlink($content_pathname);
     						if ( $super_cache_enabled == true ) {
    -							@wp_cache_rebuild_or_delete($cache_path . 'supercache/' . trailingslashit( $meta[ 'uri' ] ) . 'index.html');
    -							@wp_cache_rebuild_or_delete($cache_path . 'supercache/' . trailingslashit( $meta[ 'uri' ] ) . 'index.html.php');
    -							@wp_cache_rebuild_or_delete($cache_path . 'supercache/' . trailingslashit( $meta[ 'uri' ] ) . 'index.html.gz');
    +							foreach ( $dirs as $dir ) {
    +								@wp_cache_rebuild_or_delete( $dir . trailingslashit( $meta[ 'uri' ] ) . 'index.html');
    +								@wp_cache_rebuild_or_delete( $dir . trailingslashit( $meta[ 'uri' ] ) . 'index.html.php');
    +								@wp_cache_rebuild_or_delete( $dir . trailingslashit( $meta[ 'uri' ] ) . 'index.html.gz');
    +							}
     							do_action( 'gc_cache', 'rebuild', trailingslashit( $meta[ 'uri' ] ) );
     						}
     					}
    @@ -1032,9 +1037,11 @@
     					@unlink($meta_pathname);
     					@unlink($content_pathname);
     					if ( $super_cache_enabled == true ) {
    -						@wp_cache_rebuild_or_delete($cache_path . 'supercache/' . trailingslashit( $meta[ 'uri' ] ) . 'index.html');
    -						@wp_cache_rebuild_or_delete($cache_path . 'supercache/' . trailingslashit( $meta[ 'uri' ] ) . 'index.html.php');
    -						@wp_cache_rebuild_or_delete($cache_path . 'supercache/' . trailingslashit( $meta[ 'uri' ] ) . 'index.html.gz');
    +						foreach ( $dirs as $dir ) {
    +							@wp_cache_rebuild_or_delete( $dir . trailingslashit( $meta[ 'uri' ] ) . 'index.html');
    +							@wp_cache_rebuild_or_delete( $dir . trailingslashit( $meta[ 'uri' ] ) . 'index.html.php');
    +							@wp_cache_rebuild_or_delete( $dir . trailingslashit( $meta[ 'uri' ] ) . 'index.html.gz');
    +						}
     						do_action( 'gc_cache', 'rebuild', trailingslashit( $meta[ 'uri' ] ) );
     					}
     				}
    Index: wp-content/plugins/wp-super-cache/wp-cache.php
    ===================================================================
    --- wp-content/plugins/wp-super-cache/wp-cache.php	(revision 359498)
    +++ wp-content/plugins/wp-super-cache/wp-cache.php	(working copy)
    @@ -2467,13 +2467,15 @@
     }
    
     function clear_post_supercache( $post_id ) {
    -	$dir = get_current_url_supercache_dir( $post_id );
    -	if ( file_exists( $dir . 'index.html' ) ) {
    -		@unlink( $dir . 'index.html' );
    +	$dirs = get_current_url_supercache_dirs( $post_id );
    +	foreach ( $dirs as $dir ) {
    +		if ( file_exists( $dir . 'index.html' ) ) {
    +			@unlink( $dir . 'index.html' );
    +		}
    +		if ( file_exists( $dir . 'index.html.gz' ) ) {
    +			@unlink( $dir . 'index.html.gz' );
    +		}
     	}
    -	if ( file_exists( $dir . 'index.html.gz' ) ) {
    -		@unlink( $dir . 'index.html.gz' );
    -	}
     }
    
     function wp_cron_preload_cache() {
Viewing 7 replies - 1 through 7 (of 7 total)
  • Do you have other code that uses the “supercache_dirs” filter to write/serve the mobile cache files to/from a different directory? I presume it rewrites the single entry in the $dirs array so it’s pointing at the mobile cache dir when those clients are detected?

    Thread Starter Simon Wheatley

    (@simonwheatley)

    I do, yes. The code is in the regular WP theme and the WP Touch Pro theme, so the regular theme filters when it’s a desktop browser and WPTP takes over when mobile agents are detected. Here’s that code:

    /**
     * Hooks the WP Super Cache supercache_dir filter to specify
     * a particular directory to cache into.
     *
     * @param string $dir A portion of the directory path
     * @return string A similar portion of the directory path
     **/
    public function supercache_dir( $dir ) {
    	$dir = "desktop/" . $dir;
    	return $dir;
    }

    The WPTP function is similar, but specifies $dir = "wptouchpro/" . $dir;.

    Thanks for taking a look at this.

    That makes a lot of sense. As I said on Twitter I’ll try to expand your code so that mobile support will automatically create the second (or more) directory for the cache mobile user. Thanks for the patch!

    Am I right in presuming this is only useful when “late init” is enabled? The theme directory will have to be loaded by the detector plugin, which then adds the filter on $dirs.

    I’ll try adding support for do_cacheaction() and add_cacheaction() so a wp-super-cache plugin can be used to modify the directory path while serving the cached file.

    Thread Starter Simon Wheatley

    (@simonwheatley)

    I don’t have late init enabled, but my static cache files are definitely being split into the specified custom folders. What were you expecting to require late init? What’s the benefit to do_cacheaction over regular WP hooks ( I think I don’t get the cacheaction hooks properly)?

    I didn’t think apply_filters or the theme files would be loaded without late init being set. I’ll test it myself and see what happens.

    Thread Starter Simon Wheatley

    (@simonwheatley)

    Quick note: I’ve not tested my approach with anything other than super cached files.

Viewing 7 replies - 1 through 7 (of 7 total)
  • The topic ‘Patch allowing multiple static cache dirs for WP Super Cache’ is closed to new replies.