public function add_taxonomy_clauses( array $args, array $chosen_taxonomies ): array {
if ( empty( $chosen_taxonomies ) ) {
return $args;
}
global $wpdb;
$tax_queries = array();
$all_terms = get_terms(
array(
'taxonomy' => array_keys( $chosen_taxonomies ),
'slug' => array_merge( ...array_values( $chosen_taxonomies ) ),
'hide_empty' => false,
)
);
if ( is_wp_error( $all_terms ) ) {
/**
* No error logging needed here because:
* 1. Taxonomy existence is already validated in the initial get_terms() call above
* 2. get_terms() only returns WP_Error for invalid taxonomy or rare DB connection issues
* 3. If the taxonomy was invalid, we would have failed earlier and never reached this code
* 4. Database errors would likely affect the entire request, not just this call
*/
return $args;
}
$term_ids_by_taxonomy = array();
foreach ( $all_terms as $term ) {
$term_ids_by_taxonomy[ $term->taxonomy ][] = $term->term_id;
}
foreach ( $term_ids_by_taxonomy as $taxonomy => $term_ids ) {
if ( empty( $term_ids ) ) {
continue;
}
if ( is_taxonomy_hierarchical( $taxonomy ) ) {
$expanded_term_ids = $term_ids;
foreach ( $term_ids as $term_id ) {
$cache_key = WC_Cache_Helper::get_cache_prefix( CacheController::CACHE_GROUP ) . 'child_terms_' . $taxonomy . '_' . $term_id;
$children = wp_cache_get( $cache_key );
if ( false === $children ) {
$children = get_terms(
array(
'taxonomy' => $taxonomy,
'child_of' => $term_id,
'fields' => 'ids',
'hide_empty' => false,
)
);
if ( ! is_wp_error( $children ) ) {
wp_cache_set( $cache_key, $children, '', HOUR_IN_SECONDS );
} else {
$children = array();
}
}
$expanded_term_ids = array_merge( $expanded_term_ids, $children );
}
$term_ids = array_unique( $expanded_term_ids );
}
$term_ids_list = '(' . implode( ',', array_map( 'absint', $term_ids ) ) . ')';
/*
* Use EXISTS subquery for taxonomy filtering for several key benefits:
*
* 1. Performance: EXISTS stops execution as soon as the first matching row is found,
* making it faster than JOIN approaches that need to process all matches.
*
* 2. No duplicate rows: Unlike JOINs, EXISTS doesn't create duplicate rows when
* a product has multiple matching terms, eliminating the need for DISTINCT.
*
* 3. Clean boolean logic: We only care IF a product has the terms, not HOW MANY
* or which specific ones, making EXISTS semantically correct.
*
* 4. Efficient combination: Multiple taxonomy filters can be combined with AND
* without complex GROUP BY logic or performance degradation.
*/
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQL.NotPrepared
$tax_queries[] = $wpdb->prepare(
"EXISTS (
SELECT 1 FROM {$wpdb->term_relationships} tr
INNER JOIN {$wpdb->term_taxonomy} tt ON tr.term_taxonomy_id = tt.term_taxonomy_id
WHERE tr.object_id = {$wpdb->posts}.ID
AND tt.taxonomy = %s
AND tt.term_id IN {$term_ids_list}
)",
$taxonomy
);
}
if ( ! empty( $tax_queries ) ) {
$args['where'] .= ' AND (' . implode( ' AND ', $tax_queries ) . ')';
} else {
$args['where'] .= ' AND 1=0';
}
return $args;
}