WC_Cache_Helper::prevent_cachingpublic staticWC 3.6.0

Prevent caching on certain pages.

Method of the class: WC_Cache_Helper{}

No Hooks.

Returns

Array. string> Filtered headers.

Usage

$result = WC_Cache_Helper::prevent_caching( $headers );
$headers(required)
.

Changelog

Since 3.6.0 Introduced.
Since 10.1.0 This is now a callback for the wp_headers as opposed to a callback for the wp action.

WC_Cache_Helper::prevent_caching() code WC 11.0.0

public static function prevent_caching( $headers ) {
	if ( ! is_blog_installed() ) {
		return $headers;
	}

	// Optimization note: this is the earliest stage at which we can bulk-prime pages data. As a result, we
	// prime data for all pages used in is_page checks across the core, even if only a subset is required here.
	$pages                    = array( 'cart', 'checkout', 'coming_soon', 'myaccount', 'shop', 'terms' );
	$woocommerce_page_options = array_map( static fn ( string $page ) => sprintf( 'woocommerce_%s_page_id', $page ), $pages );
	wp_prime_option_caches( $woocommerce_page_options );
	$woocommerce_page_ids = array_combine( $pages, array_map( static fn ( string $page ) => wc_get_page_id( $page ), $pages ) );
	_prime_post_caches( array_values( array_filter( $woocommerce_page_ids ) ), false, false );

	$page_ids = array_filter( array( $woocommerce_page_ids['cart'], $woocommerce_page_ids['checkout'], $woocommerce_page_ids['myaccount'] ) );
	if ( ! is_page( $page_ids ) ) {
		return $headers;
	}

	self::set_nocache_constants();

	// Gather the original Cache-Control directives as well as the nocache ones to merge into one new Cache-Control header.
	if ( isset( $headers['Cache-Control'] ) ) {
		$old_directives = preg_split( '/\s*,\s*/', trim( $headers['Cache-Control'] ) );
	} else {
		$old_directives = array();
	}
	$nocache_headers = wp_get_nocache_headers();
	if ( isset( $nocache_headers['Cache-Control'] ) ) {
		$new_directives = preg_split( '/\s*,\s*/', trim( $nocache_headers['Cache-Control'] ) );
	} else {
		$new_directives = array();
	}

	$headers = array_merge( $headers, $nocache_headers );

	/*
	 * If the user is not logged in, remove the `no-store` directive so that bfcache is not blocked for visitors,
	 * allowing them to benefit from instant back/forward navigations in the storefront. This essentially undoes
	 * <https://core.trac.wordpress.org/ticket/61942> which seems to have been excessive since the `private`
	 * directive was already being sent to prevent the page from being cached in a proxy server.
	 *
	 * Note that <https://core.trac.wordpress.org/ticket/63636> proposes removing `no-store` for logged-in users as
	 * well. When that happens, the following if statement can be removed since core would no longer be sending
	 * `no-store` in the first place.
	 *
	 * If a site really wants to enforce the `no-store` directive for some reason, they can do so by making sure
	 * that the `no-store` directive is added to the `Cache-Control` header via the `wp_headers` filter, for
	 * example:
	 *
	 *     add_filter( 'wp_headers', function ( $headers ) {
	 *         if ( isset( $headers['Cache-Control'] ) ) {
	 *             $directives = preg_split( ':\s*,\s*:', trim( $headers['Cache-Control'] ) );
	 *             if ( in_array( 'private', $directives, true ) ) {
	 *                 $headers['Cache-Control'] = join(
	 *                     ', ',
	 *                     array_unique(
	 *                         array_merge(
	 *                             $directives,
	 *                             array( 'no-store' )
	 *                         )
	 *                     )
	 *                 );
	 *             }
	 *         }
	 *         return $headers;
	 *     } );
	 */
	if ( ! is_user_logged_in() ) {
		$new_directives = array_diff( $new_directives, array( 'no-store' ) );
	}

	$headers['Cache-Control'] = implode( ', ', array_unique( array_merge( $old_directives, $new_directives ) ) );

	return $headers;
}