Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Invalidate script data cache when site URL, scheme, or plugin name changes #10278

Merged
merged 9 commits into from
Aug 3, 2023
49 changes: 46 additions & 3 deletions src/Assets/Api.php
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,20 @@ class Api {
*/
private $script_data = null;

/**
* Stores the hash for the script data, made up of the site url, plugin version and package path.
*
* @var string
*/
private $script_data_hash;

/**
* Stores the transient key used to cache the script data. This will change if the site is accessed via HTTPS or HTTP.
*
* @var string
*/
private $script_data_transient_key = 'woocommerce_blocks_asset_api_script_data';

/**
* Reference to the Package instance
*
Expand All @@ -47,6 +61,15 @@ class Api {
public function __construct( Package $package ) {
$this->package = $package;
$this->disable_cache = ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) || ! $this->package->feature()->is_production_environment();

// If the site is accessed via HTTPS, change the transient key. This is to prevent the script URLs being cached
// with the first scheme they are accessed on after cache expiry.
if ( is_ssl() ) {
$this->script_data_transient_key .= '_ssl';
}
if ( ! $this->disable_cache ) {
$this->script_data_hash = $this->get_script_data_hash();
}
add_action( 'shutdown', array( $this, 'update_script_data_cache' ), 20 );
}

Expand Down Expand Up @@ -92,6 +115,17 @@ public function get_block_metadata_path( $block_name, $path = '' ) {
return $path_to_metadata_from_plugin_root;
}

/**
* Generates a hash containing the site url, plugin version and package path.
*
* Moving the plugin, changing the version, or changing the site url will result in a new hash and the cache will be invalidated.
*
* @return string The generated hash.
*/
private function get_script_data_hash() {
return md5( get_option( 'siteurl', '' ) . $this->package->get_version() . $this->package->get_path() );
}

/**
* Initialize and load cached script data from the transient cache.
*
Expand All @@ -102,9 +136,17 @@ private function get_cached_script_data() {
return [];
}

$transient_value = json_decode( (string) get_transient( 'woocommerce_blocks_asset_api_script_data' ), true );
$transient_value = json_decode( (string) get_transient( $this->script_data_transient_key ), true );
wavvves marked this conversation as resolved.
Show resolved Hide resolved

if ( empty( $transient_value ) || empty( $transient_value['script_data'] ) || empty( $transient_value['version'] ) || $transient_value['version'] !== $this->package->get_version() ) {
if (
json_last_error() !== JSON_ERROR_NONE ||
empty( $transient_value ) ||
empty( $transient_value['script_data'] ) ||
empty( $transient_value['version'] ) ||
$transient_value['version'] !== $this->package->get_version() ||
empty( $transient_value['hash'] ) ||
$transient_value['hash'] !== $this->script_data_hash
) {
return [];
}

Expand All @@ -119,11 +161,12 @@ public function update_script_data_cache() {
return;
}
set_transient(
'woocommerce_blocks_asset_api_script_data',
$this->script_data_transient_key,
wp_json_encode(
array(
'script_data' => $this->script_data,
'version' => $this->package->get_version(),
'hash' => $this->script_data_hash,
)
),
DAY_IN_SECONDS * 30
Expand Down