Title: Patch allowing multiple static cache dirs for WP Super Cache
Last modified: August 19, 2016

---

# Patch allowing multiple static cache dirs for WP Super Cache

 *  [Simon Wheatley](https://wordpress.org/support/users/simonwheatley/)
 * (@simonwheatley)
 * [15 years, 2 months ago](https://wordpress.org/support/topic/patch-allowing-multiple-static-cache-dirs-for-wp-super-cache/)
 * 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( 'http://', '', 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)

 *  Plugin Author [Donncha O Caoimh (a11n)](https://wordpress.org/support/users/donncha/)
 * (@donncha)
 * [15 years, 2 months ago](https://wordpress.org/support/topic/patch-allowing-multiple-static-cache-dirs-for-wp-super-cache/#post-1973566)
 * 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](https://wordpress.org/support/users/simonwheatley/)
 * (@simonwheatley)
 * [15 years, 2 months ago](https://wordpress.org/support/topic/patch-allowing-multiple-static-cache-dirs-for-wp-super-cache/#post-1973591)
 * 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.
 *  Plugin Author [Donncha O Caoimh (a11n)](https://wordpress.org/support/users/donncha/)
 * (@donncha)
 * [15 years, 2 months ago](https://wordpress.org/support/topic/patch-allowing-multiple-static-cache-dirs-for-wp-super-cache/#post-1973592)
 * 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!
 *  Plugin Author [Donncha O Caoimh (a11n)](https://wordpress.org/support/users/donncha/)
 * (@donncha)
 * [15 years, 2 months ago](https://wordpress.org/support/topic/patch-allowing-multiple-static-cache-dirs-for-wp-super-cache/#post-1973632)
 * 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](https://wordpress.org/support/users/simonwheatley/)
 * (@simonwheatley)
 * [15 years, 2 months ago](https://wordpress.org/support/topic/patch-allowing-multiple-static-cache-dirs-for-wp-super-cache/#post-1973633)
 * 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)?
 *  Plugin Author [Donncha O Caoimh (a11n)](https://wordpress.org/support/users/donncha/)
 * (@donncha)
 * [15 years, 2 months ago](https://wordpress.org/support/topic/patch-allowing-multiple-static-cache-dirs-for-wp-super-cache/#post-1973634)
 * 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](https://wordpress.org/support/users/simonwheatley/)
 * (@simonwheatley)
 * [15 years, 2 months ago](https://wordpress.org/support/topic/patch-allowing-multiple-static-cache-dirs-for-wp-super-cache/#post-1973635)
 * 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.

 * ![](https://ps.w.org/wp-super-cache/assets/icon-256x256.png?rev=3506220)
 * [WP Super Cache](https://wordpress.org/plugins/wp-super-cache/)
 * [Frequently Asked Questions](https://wordpress.org/plugins/wp-super-cache/#faq)
 * [Support Threads](https://wordpress.org/support/plugin/wp-super-cache/)
 * [Active Topics](https://wordpress.org/support/plugin/wp-super-cache/active/)
 * [Unresolved Topics](https://wordpress.org/support/plugin/wp-super-cache/unresolved/)
 * [Reviews](https://wordpress.org/support/plugin/wp-super-cache/reviews/)

 * 7 replies
 * 2 participants
 * Last reply from: [Simon Wheatley](https://wordpress.org/support/users/simonwheatley/)
 * Last activity: [15 years, 2 months ago](https://wordpress.org/support/topic/patch-allowing-multiple-static-cache-dirs-for-wp-super-cache/#post-1973635)
 * Status: not resolved