Skip to content
This repository has been archived by the owner on Feb 23, 2024. It is now read-only.

Fix Product categories, Product Tags & Keyword filter not working in Products block #8377

Merged
merged 12 commits into from
Feb 21, 2023
Merged
72 changes: 67 additions & 5 deletions src/BlockTypes/ProductQuery.php
Original file line number Diff line number Diff line change
Expand Up @@ -160,8 +160,10 @@ public function build_query( $query ) {
$common_query_values,
$this->get_global_query( $parsed_block ),
$this->get_custom_orderby_query( $query['orderby'] ),
$this->get_queries_by_attributes( $parsed_block ),
$this->get_queries_by_applied_filters()
$this->get_queries_by_custom_attributes( $parsed_block ),
$this->get_queries_by_applied_filters(),
$this->get_filter_by_taxonomies_query( $query ),
$this->get_filter_by_keyword_query( $query )
);
}

Expand All @@ -182,7 +184,7 @@ private function get_products_ids_by_attributes( $parsed_block ) {
'meta_query' => array(),
'tax_query' => array(),
),
$this->get_queries_by_attributes( $parsed_block ),
$this->get_queries_by_custom_attributes( $parsed_block ),
$this->get_global_query( $parsed_block )
);

Expand Down Expand Up @@ -491,7 +493,7 @@ private function get_queries_by_applied_filters() {
* @param array $parsed_block The Product Query that being rendered.
* @return array
*/
private function get_queries_by_attributes( $parsed_block ) {
private function get_queries_by_custom_attributes( $parsed_block ) {
$query = $parsed_block['attrs']['query'];
$on_sale_enabled = isset( $query['__woocommerceOnSale'] ) && true === $query['__woocommerceOnSale'];
$attributes_query = isset( $query['__woocommerceAttributes'] ) ? $this->get_product_attributes_query( $query['__woocommerceAttributes'] ) : array();
Expand Down Expand Up @@ -625,7 +627,6 @@ function( $stock_status ) {
'key' => '_stock_status',
'value' => $filtered_stock_status_values,
'operator' => 'IN',

),
),
);
Expand Down Expand Up @@ -814,4 +815,65 @@ function( $rating ) use ( $product_visibility_terms ) {
);
}


/**
* Return a query to filter products by taxonomies (product categories, product tags, etc.)
*
* For example:
* User could provide "Product Categories" using "Filters" ToolsPanel available in Inspector Controls.
* We use this function to extract it's query from $tax_query.
*
* For example, this is how the query for product categories will look like in $tax_query array:
* Array
* (
* [taxonomy] => product_cat
* [terms] => Array
* (
* [0] => 36
* )
* )
*
* For product categories, taxonomy would be "product_tag"
*
* @param array $query WP_Query.
* @return array Query to filter products by taxonomies.
*/
private function get_filter_by_taxonomies_query( $query ): array {
if ( ! isset( $query['tax_query'] ) || ! is_array( $query['tax_query'] ) ) {
return [];
}

$tax_query = $query['tax_query'];
/**
* Get an array of taxonomy names associated with the "product" post type because
* we also want to include custom taxonomies associated with the "product" post type.
*/
$product_taxonomies = get_taxonomies( array( 'object_type' => array( 'product' ) ), 'names' );
$result = array_filter(
$tax_query,
function( $item ) use ( $product_taxonomies ) {
return isset( $item['taxonomy'] ) && in_array( $item['taxonomy'], $product_taxonomies, true );
}
);

return ! empty( $result ) ? [ 'tax_query' => $result ] : [];
}

/**
* Returns the keyword filter from the given query.
*
* @param WP_Query $query The query to extract the keyword filter from.
* @return array The keyword filter, or an empty array if none is found.
*/
private function get_filter_by_keyword_query( $query ): array {
if ( ! is_array( $query ) ) {
return [];
}

if ( isset( $query['s'] ) ) {
return [ 's' => $query['s'] ];
}

return [];
}
}