Invalidate query transients to avoid cache flush
Part of #5777. These transients are required and cannot be predicted. If not using an external cache system, the DB is cleared still to keep size down after invalidation. For these 2 transients, invalidation occurs when visibility altering product attributes are edited.
This commit is contained in:
parent
3974c1028a
commit
ee48dcd5fd
|
@ -23,6 +23,37 @@ class WC_Cache_Helper {
|
|||
add_action( 'admin_notices', array( __CLASS__, 'notices' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get transient version
|
||||
*
|
||||
* When using transients with unpredictable names, e.g. those containing an md5
|
||||
* hash in the name, we need a way to invalidate them all at once.
|
||||
*
|
||||
* When using default WP transients we're able to do this with a DB query to
|
||||
* delete transients manually.
|
||||
*
|
||||
* With external cache however, this isn't possible. Instead, this function is used
|
||||
* to append a unique string (based on time()) to each transient. When transients
|
||||
* are invalidated, the transient version will increment and data will be regenerated.
|
||||
*
|
||||
* Raised in issue https://github.com/woothemes/woocommerce/issues/5777
|
||||
* Adapted from ideas in http://tollmanz.com/invalidation-schemes/
|
||||
*
|
||||
* @param string $group Name for the group of transients we need to invalidate
|
||||
* @param boolean $refresh true to force a new version
|
||||
* @return string transient version based on time(), 10 digits
|
||||
*/
|
||||
public static function get_transient_version( $group, $refresh = false ) {
|
||||
$transient_name = $group . '-transient-version';
|
||||
$transient_value = get_transient( $key );
|
||||
|
||||
if ( false === $transient_value || true === $refresh ) {
|
||||
$transient_value = time();
|
||||
set_transient( $transient_name, $transient_value );
|
||||
}
|
||||
return $transient_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prevent caching on dynamic pages.
|
||||
*
|
||||
|
|
|
@ -59,15 +59,21 @@ class WC_Post_Data {
|
|||
* Delete product view transients when needed e.g. when post status changes, or visibility/stock status is modified.
|
||||
*/
|
||||
public static function delete_product_query_transients() {
|
||||
global $wpdb;
|
||||
// Increments the transient version to invalidate cache
|
||||
WC_Cache_Helper::get_transient_version( 'product_query', true );
|
||||
|
||||
if ( wp_using_ext_object_cache() ) {
|
||||
wp_cache_flush(); // There isn't a reliable method of looking up the names, so flush the cache.
|
||||
return;
|
||||
// If not using an external caching system, we can clear the transients out manually and avoid filling our DB
|
||||
if ( ! wp_using_ext_object_cache() ) {
|
||||
global $wpdb;
|
||||
|
||||
$wpdb->query( "
|
||||
DELETE FROM `$wpdb->options`
|
||||
WHERE `option_name` LIKE ('\_transient\_wc\_uf\_pid\_%')
|
||||
OR `option_name` LIKE ('\_transient\_timeout\_wc\_uf\_pid\_%')
|
||||
OR `option_name` LIKE ('\_transient\_wc\_products\_will\_display\_%')
|
||||
OR `option_name` LIKE ('\_transient\_timeout\_wc\_products\_will\_display\_%')
|
||||
" );
|
||||
}
|
||||
|
||||
$wpdb->query( "DELETE FROM `$wpdb->options` WHERE `option_name` LIKE ('\_transient\_wc\_uf\_pid\_%') OR `option_name` LIKE ('\_transient\_timeout\_wc\_uf\_pid\_%')" );
|
||||
$wpdb->query( "DELETE FROM `$wpdb->options` WHERE `option_name` LIKE ('\_transient\_wc\_products\_will\_display\_%') OR `option_name` LIKE ('\_transient\_timeout\_wc\_products\_will\_display\_%')" );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -435,7 +435,7 @@ class WC_Query {
|
|||
unset( $current_wp_query['paged'] );
|
||||
|
||||
// Generate a transient name based on current query
|
||||
$transient_name = 'wc_uf_pid_' . md5( http_build_query( $current_wp_query ) );
|
||||
$transient_name = 'wc_uf_pid_' . md5( http_build_query( $current_wp_query ) . WC_Cache_Helper::get_transient_version( 'product_query' ) );
|
||||
$transient_name = ( is_search() ) ? $transient_name . '_s' : $transient_name;
|
||||
|
||||
if ( false === ( $unfiltered_product_ids = get_transient( $transient_name ) ) ) {
|
||||
|
@ -464,16 +464,18 @@ class WC_Query {
|
|||
$this->unfiltered_product_ids = $unfiltered_product_ids;
|
||||
|
||||
// Also store filtered posts ids...
|
||||
if ( sizeof( $this->post__in ) > 0 )
|
||||
if ( sizeof( $this->post__in ) > 0 ) {
|
||||
$this->filtered_product_ids = array_intersect( $this->unfiltered_product_ids, $this->post__in );
|
||||
else
|
||||
} else {
|
||||
$this->filtered_product_ids = $this->unfiltered_product_ids;
|
||||
}
|
||||
|
||||
// And filtered post ids which just take layered nav into consideration (to find max price in the price widget)
|
||||
if ( sizeof( $this->layered_nav_post__in ) > 0 )
|
||||
if ( sizeof( $this->layered_nav_post__in ) > 0 ) {
|
||||
$this->layered_nav_product_ids = array_intersect( $this->unfiltered_product_ids, $this->layered_nav_post__in );
|
||||
else
|
||||
} else {
|
||||
$this->layered_nav_product_ids = $this->unfiltered_product_ids;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1340,7 +1340,9 @@ if ( ! function_exists( 'woocommerce_products_will_display' ) ) {
|
|||
return true;
|
||||
}
|
||||
|
||||
if ( false === ( $products_will_display = get_transient( 'wc_products_will_display_' . $parent_id ) ) ) {
|
||||
$transient_name = 'wc_products_will_display_' . $parent_id . WC_Cache_Helper::get_transient_version( 'product_query' );
|
||||
|
||||
if ( false === ( $products_will_display = get_transient( $transient_name ) ) ) {
|
||||
$has_children = $wpdb->get_col( $wpdb->prepare( "SELECT term_id FROM {$wpdb->term_taxonomy} WHERE parent = %d AND taxonomy = %s", $parent_id, $taxonomy ) );
|
||||
|
||||
if ( $has_children ) {
|
||||
|
@ -1363,7 +1365,7 @@ if ( ! function_exists( 'woocommerce_products_will_display' ) ) {
|
|||
}
|
||||
}
|
||||
|
||||
set_transient( 'wc_products_will_display_' . $parent_id, $products_will_display, YEAR_IN_SECONDS );
|
||||
set_transient( $transient_name, $products_will_display, YEAR_IN_SECONDS );
|
||||
|
||||
return $products_will_display;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue