Automattic\WooCommerce\Internal\ProductAttributesLookup
Filterer::filter_by_attribute_post_clauses()
Adds post clauses for filtering via lookup table. This method should be invoked within a posts_clauses
Метод класса: Filterer{}
Хуков нет.
Возвращает
Массив
. The updated product query clauses.
Использование
$Filterer = new Filterer(); $Filterer->filter_by_attribute_post_clauses( $args, $wp_query, $attributes_to_filter_by );
- $args(массив) (обязательный)
- Product query clauses as supplied to the posts_clauses
- $wp_query(\WP_Query) (обязательный)
- Current product query as supplied to the posts_clauses
- $attributes_to_filter_by(массив) (обязательный)
- Attribute filtering data as generated by WC_Query::get_layered_nav_chosen_attributes.
Код Filterer::filter_by_attribute_post_clauses() Filterer::filter by attribute post clauses WC 9.4.2
public function filter_by_attribute_post_clauses( array $args, \WP_Query $wp_query, array $attributes_to_filter_by ) { global $wpdb; if ( ! $wp_query->is_main_query() || ! $this->filtering_via_lookup_table_is_active() ) { return $args; } // The extra derived table ("SELECT product_or_parent_id FROM") is needed for performance // (causes the filtering subquery to be executed only once). $clause_root = " {$wpdb->posts}.ID IN ( SELECT product_or_parent_id FROM ("; if ( 'yes' === get_option( 'woocommerce_hide_out_of_stock_items' ) ) { $in_stock_clause = ' AND in_stock = 1'; } else { $in_stock_clause = ''; } $attribute_ids_for_and_filtering = array(); $clauses = array(); foreach ( $attributes_to_filter_by as $taxonomy => $data ) { $all_terms = get_terms( $taxonomy, array( 'hide_empty' => false ) ); $term_ids_by_slug = wp_list_pluck( $all_terms, 'term_id', 'slug' ); $term_ids_to_filter_by = array_values( array_intersect_key( $term_ids_by_slug, array_flip( $data['terms'] ) ) ); $term_ids_to_filter_by = array_map( 'absint', $term_ids_to_filter_by ); $term_ids_to_filter_by_list = '(' . join( ',', $term_ids_to_filter_by ) . ')'; $is_and_query = 'and' === $data['query_type']; $count = count( $term_ids_to_filter_by ); if ( 0 !== $count ) { if ( $is_and_query && $count > 1 ) { $attribute_ids_for_and_filtering = array_merge( $attribute_ids_for_and_filtering, $term_ids_to_filter_by ); } else { $clauses[] = " {$clause_root} SELECT product_or_parent_id FROM {$this->lookup_table_name} lt WHERE term_id in {$term_ids_to_filter_by_list} {$in_stock_clause} )"; } } } if ( ! empty( $attribute_ids_for_and_filtering ) ) { $count = count( $attribute_ids_for_and_filtering ); $term_ids_to_filter_by_list = '(' . join( ',', $attribute_ids_for_and_filtering ) . ')'; $clauses[] = " {$clause_root} SELECT product_or_parent_id FROM {$this->lookup_table_name} lt WHERE is_variation_attribute=0 {$in_stock_clause} AND term_id in {$term_ids_to_filter_by_list} GROUP BY product_id HAVING COUNT(product_id)={$count} UNION SELECT product_or_parent_id FROM {$this->lookup_table_name} lt WHERE is_variation_attribute=1 {$in_stock_clause} AND term_id in {$term_ids_to_filter_by_list} )"; } if ( ! empty( $clauses ) ) { // "temp" is needed because the extra derived tables require an alias. $args['where'] .= ' AND (' . join( ' temp ) AND ', $clauses ) . ' temp ))'; } elseif ( ! empty( $attributes_to_filter_by ) ) { $args['where'] .= ' AND 1=0'; } return $args; }