Store product ids for terms in term meta rather than transient

Data is kept in sync by looking at when terms are set for an object and
then clearing the meta for old and new terms.
This commit is contained in:
Mike Jolley 2015-11-14 16:25:09 +00:00
parent 28b02fd3dd
commit 6892d73ea9
3 changed files with 49 additions and 27 deletions

View File

@ -623,3 +623,43 @@ function wc_change_term_counts( $terms, $taxonomies ) {
return $terms; return $terms;
} }
add_filter( 'get_terms', 'wc_change_term_counts', 10, 2 ); add_filter( 'get_terms', 'wc_change_term_counts', 10, 2 );
/**
* Return products in a given term, and cache value.
*
* To keep in sync, product_count will be cleared on "set_object_terms".
*
* @param int $term_id
* @param string $taxonomy
* @return array
*/
function wc_get_term_product_ids( $term_id, $taxonomy ) {
$product_ids = get_woocommerce_term_meta( $term_id, 'product_ids', true );
if ( false === $product_ids || ! is_array( $product_ids ) ) {
$product_ids = get_objects_in_term( $term_id, $taxonomy );
update_woocommerce_term_meta( $term_id, 'product_ids', $product_ids );
}
return $product_ids;
}
/**
* When a post is updated and terms recounted (called by _update_post_term_count), clear the ids.
* @param int $term_id
* @param int $object_id Object ID.
* @param array $terms An array of object terms.
* @param array $tt_ids An array of term taxonomy IDs.
* @param string $taxonomy Taxonomy slug.
* @param bool $append Whether to append new terms to the old terms.
* @param array $old_tt_ids Old array of term taxonomy IDs.
*/
function wc_clear_term_product_ids( $object_id, $terms, $tt_ids, $taxonomy, $append, $old_tt_ids ) {
foreach ( $old_tt_ids as $term_id ) {
delete_woocommerce_term_meta( $term_id, 'product_ids' );
}
foreach ( $tt_ids as $term_id ) {
delete_woocommerce_term_meta( $term_id, 'product_ids' );
}
}
add_action( 'set_object_terms', 'wc_clear_term_product_ids', 10, 6 );

View File

@ -206,10 +206,8 @@ function wc_paying_customer( $order_id ) {
} }
add_action( 'woocommerce_order_status_completed', 'wc_paying_customer' ); add_action( 'woocommerce_order_status_completed', 'wc_paying_customer' );
/** /**
* Checks if a user (by email) has bought an item. * Checks if a user (by email or ID or both) has bought an item.
*
* @param string $customer_email * @param string $customer_email
* @param int $user_id * @param int $user_id
* @param int $product_id * @param int $product_id
@ -252,11 +250,11 @@ function wc_customer_bought_product( $customer_email, $user_id, $product_id ) {
AND im.meta_value != 0 AND im.meta_value != 0
AND pm.meta_value IN ( '" . implode( "','", $customer_data ) . "' ) AND pm.meta_value IN ( '" . implode( "','", $customer_data ) . "' )
" ); " );
$result = array_map( 'intval', $result ); $result = array_map( 'absint', $result );
set_transient( $transient_name, $result, DAY_IN_SECONDS * 30 ); set_transient( $transient_name, $result, DAY_IN_SECONDS * 30 );
} }
return in_array( (int) $product_id, $result ); return in_array( absint( $product_id ), $result );
} }
/** /**

View File

@ -187,16 +187,8 @@ class WC_Widget_Layered_Nav extends WC_Widget {
continue; continue;
} }
// Get count based on current view - uses transients // Get count based on current view
$transient_name = 'wc_ln_count_' . md5( sanitize_key( $taxonomy ) . sanitize_key( $term->term_taxonomy_id ) ); $_products_in_term = wc_get_term_product_ids( $term->term_id, $taxonomy );
if ( false === ( $_products_in_term = get_transient( $transient_name ) ) ) {
$_products_in_term = get_objects_in_term( $term->term_id, $taxonomy );
set_transient( $transient_name, $_products_in_term, DAY_IN_SECONDS * 30 );
}
$option_is_set = ( isset( $_chosen_attributes[ $taxonomy ] ) && in_array( $term->term_id, $_chosen_attributes[ $taxonomy ]['terms'] ) ); $option_is_set = ( isset( $_chosen_attributes[ $taxonomy ] ) && in_array( $term->term_id, $_chosen_attributes[ $taxonomy ]['terms'] ) );
// If this is an AND query, only show options with count > 0 // If this is an AND query, only show options with count > 0
@ -245,15 +237,7 @@ class WC_Widget_Layered_Nav extends WC_Widget {
foreach ( $terms as $term ) { foreach ( $terms as $term ) {
// Get count based on current view - uses transients // Get count based on current view - uses transients
$transient_name = 'wc_ln_count_' . md5( sanitize_key( $taxonomy ) . sanitize_key( $term->term_taxonomy_id ) ); $_products_in_term = wc_get_term_product_ids( $term->term_id, $taxonomy );
if ( false === ( $_products_in_term = get_transient( $transient_name ) ) ) {
$_products_in_term = get_objects_in_term( $term->term_id, $taxonomy );
set_transient( $transient_name, $_products_in_term );
}
$option_is_set = ( isset( $_chosen_attributes[ $taxonomy ] ) && in_array( $term->term_id, $_chosen_attributes[ $taxonomy ]['terms'] ) ); $option_is_set = ( isset( $_chosen_attributes[ $taxonomy ] ) && in_array( $term->term_id, $_chosen_attributes[ $taxonomy ]['terms'] ) );
// skip the term for the current archive // skip the term for the current archive