WordPress.org

Ready to get started?Download WordPress

Forums

WP Super Cache
Patch allowing multiple static cache dirs for WP Super Cache (8 posts)

  1. Simon Wheatley
    Code for the People
    Posted 3 years ago #

    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() {
  2. Donncha O Caoimh
    Member
    Plugin Author

    Posted 3 years ago #

    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?

  3. Simon Wheatley
    Code for the People
    Posted 3 years ago #

    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.

  4. Donncha O Caoimh
    Member
    Plugin Author

    Posted 3 years ago #

    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!

  5. Donncha O Caoimh
    Member
    Plugin Author

    Posted 3 years ago #

    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.

  6. Simon Wheatley
    Code for the People
    Posted 3 years ago #

    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)?

  7. Donncha O Caoimh
    Member
    Plugin Author

    Posted 3 years ago #

    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.

  8. Simon Wheatley
    Code for the People
    Posted 3 years ago #

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

Topic Closed

This topic has been closed to new replies.

About this Plugin

About this Topic