diff --git a/includes/wc-term-functions.php b/includes/wc-term-functions.php index 115ccd992cc..d36ff54b6a0 100644 --- a/includes/wc-term-functions.php +++ b/includes/wc-term-functions.php @@ -623,3 +623,43 @@ function wc_change_term_counts( $terms, $taxonomies ) { return $terms; } 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 ); diff --git a/includes/wc-user-functions.php b/includes/wc-user-functions.php index 1421b6700f3..448b24aebb3 100644 --- a/includes/wc-user-functions.php +++ b/includes/wc-user-functions.php @@ -206,10 +206,8 @@ function wc_paying_customer( $order_id ) { } 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 int $user_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 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 ); } - return in_array( (int) $product_id, $result ); + return in_array( absint( $product_id ), $result ); } /** diff --git a/includes/widgets/class-wc-widget-layered-nav.php b/includes/widgets/class-wc-widget-layered-nav.php index 82f15fff62a..26abf96bad3 100644 --- a/includes/widgets/class-wc-widget-layered-nav.php +++ b/includes/widgets/class-wc-widget-layered-nav.php @@ -187,17 +187,9 @@ class WC_Widget_Layered_Nav extends WC_Widget { continue; } - // Get count based on current view - uses transients - $transient_name = 'wc_ln_count_' . md5( sanitize_key( $taxonomy ) . sanitize_key( $term->term_taxonomy_id ) ); - - 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'] ) ); + // Get count based on current view + $_products_in_term = wc_get_term_product_ids( $term->term_id, $taxonomy ); + $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 ( 'and' == $query_type ) { @@ -245,16 +237,8 @@ class WC_Widget_Layered_Nav extends WC_Widget { foreach ( $terms as $term ) { // Get count based on current view - uses transients - $transient_name = 'wc_ln_count_' . md5( sanitize_key( $taxonomy ) . sanitize_key( $term->term_taxonomy_id ) ); - - 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'] ) ); + $_products_in_term = wc_get_term_product_ids( $term->term_id, $taxonomy ); + $option_is_set = ( isset( $_chosen_attributes[ $taxonomy ] ) && in_array( $term->term_id, $_chosen_attributes[ $taxonomy ]['terms'] ) ); // skip the term for the current archive if ( $current_term == $term->term_id ) { @@ -396,7 +380,7 @@ class WC_Widget_Layered_Nav extends WC_Widget { } // End display type conditional $this->widget_end( $args ); - + if ( ! $found ) { ob_end_clean(); } else {