Fix: broken contract in StoreAPI ProductCollectionData endpoint (#45247)
* revert: use original implementation * fix: price query clause * chore: changelog * fix: passing full query state to get the correct count and avoid cache issue * Replace references to woo-gutenberg-products-block * fix php cs error * fix php cs error * Fix e2e tests for attributes count * Separated out and/or query type tests for attrs count --------- Co-authored-by: Alexandre Lara <allexandrelara@gmail.com> Co-authored-by: roykho <roykho77@gmail.com>
This commit is contained in:
parent
6fb00c4297
commit
11ec7c6255
|
@ -139,9 +139,7 @@ const AttributeFilterBlock = ( {
|
|||
taxonomy: attributeObject?.taxonomy || '',
|
||||
queryType: blockAttributes.queryType,
|
||||
},
|
||||
queryState: {
|
||||
...queryState,
|
||||
},
|
||||
queryState,
|
||||
isEditor,
|
||||
} );
|
||||
|
||||
|
|
|
@ -34,7 +34,7 @@ test.describe( 'Filter by Attributes Block - with All products Block', () => {
|
|||
// Check if the page has loaded successfully.
|
||||
await expect( page.getByText( 'Active Filters block' ) ).toBeVisible();
|
||||
|
||||
const expectedValues = [ '4', '0', '2', '2', '0' ];
|
||||
const expectedValues = [ '4', '2', '3', '4', '1' ];
|
||||
|
||||
await expect(
|
||||
page
|
||||
|
@ -57,7 +57,7 @@ test.describe( 'Filter by Attributes Block - with All products Block', () => {
|
|||
// Check if the page has loaded successfully.
|
||||
await expect( page.getByText( 'Active Filters block' ) ).toBeVisible();
|
||||
|
||||
const expectedValues = [ '4', '3', '2', '2', '0' ];
|
||||
const expectedValues = [ '4', '2', '3', '4', '1' ];
|
||||
|
||||
await expect(
|
||||
page
|
||||
|
@ -80,7 +80,7 @@ test.describe( 'Filter by Attributes Block - with All products Block', () => {
|
|||
// Check if the page has loaded successfully.
|
||||
await expect( page.getByText( 'Active Filters block' ) ).toBeVisible();
|
||||
|
||||
const expectedValues = [ '2', '0', '1', '1', '0' ];
|
||||
const expectedValues = [ '2', '2', '2', '3', '1' ];
|
||||
|
||||
await expect(
|
||||
page
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: fix
|
||||
|
||||
Fix the broken contract in the StoreAPI and the bug in the price clauses causing the incorrect filter counts.
|
|
@ -100,12 +100,49 @@ class ProductCollectionData extends AbstractRoute {
|
|||
}
|
||||
|
||||
if ( ! empty( $request['calculate_attribute_counts'] ) ) {
|
||||
foreach ( $request['calculate_attribute_counts'] as $attributes_to_count ) {
|
||||
if ( ! isset( $attributes_to_count['taxonomy'] ) ) {
|
||||
continue;
|
||||
}
|
||||
$taxonomy__or_queries = [];
|
||||
$taxonomy__and_queries = [];
|
||||
|
||||
$counts = $filters->get_attribute_counts( $request, $attributes_to_count['taxonomy'] );
|
||||
foreach ( $request['calculate_attribute_counts'] as $attributes_to_count ) {
|
||||
if ( ! empty( $attributes_to_count['taxonomy'] ) ) {
|
||||
if ( empty( $attributes_to_count['query_type'] ) || 'or' === $attributes_to_count['query_type'] ) {
|
||||
$taxonomy__or_queries[] = $attributes_to_count['taxonomy'];
|
||||
} else {
|
||||
$taxonomy__and_queries[] = $attributes_to_count['taxonomy'];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$data['attribute_counts'] = [];
|
||||
// Or type queries need special handling because the attribute, if set, needs removing from the query first otherwise counts would not be correct.
|
||||
if ( $taxonomy__or_queries ) {
|
||||
foreach ( $taxonomy__or_queries as $taxonomy ) {
|
||||
$filter_request = clone $request;
|
||||
$filter_attributes = $filter_request->get_param( 'attributes' );
|
||||
|
||||
if ( ! empty( $filter_attributes ) ) {
|
||||
$filter_attributes = array_filter(
|
||||
$filter_attributes,
|
||||
function ( $query ) use ( $taxonomy ) {
|
||||
return $query['attribute'] !== $taxonomy;
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
$filter_request->set_param( 'attributes', $filter_attributes );
|
||||
$counts = $filters->get_attribute_counts( $filter_request, [ $taxonomy ] );
|
||||
|
||||
foreach ( $counts as $key => $value ) {
|
||||
$data['attribute_counts'][] = (object) [
|
||||
'term' => $key,
|
||||
'count' => $value,
|
||||
];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( $taxonomy__and_queries ) {
|
||||
$counts = $filters->get_attribute_counts( $request, $taxonomy__and_queries );
|
||||
|
||||
foreach ( $counts as $key => $value ) {
|
||||
$data['attribute_counts'][] = (object) [
|
||||
|
|
|
@ -405,9 +405,9 @@ class ProductQuery {
|
|||
$min_price_filter = $this->prepare_price_filter( $wp_query->get( 'min_price' ) );
|
||||
|
||||
if ( $adjust_for_taxes ) {
|
||||
$args['where'] .= $this->get_price_filter_query_for_displayed_taxes( $min_price_filter, 'min_price', '>=' );
|
||||
$args['where'] .= $this->get_price_filter_query_for_displayed_taxes( $min_price_filter, 'max_price', '>=' );
|
||||
} else {
|
||||
$args['where'] .= $wpdb->prepare( ' AND wc_product_meta_lookup.min_price >= %f ', $min_price_filter );
|
||||
$args['where'] .= $wpdb->prepare( ' AND wc_product_meta_lookup.max_price >= %f ', $min_price_filter );
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -415,9 +415,9 @@ class ProductQuery {
|
|||
$max_price_filter = $this->prepare_price_filter( $wp_query->get( 'max_price' ) );
|
||||
|
||||
if ( $adjust_for_taxes ) {
|
||||
$args['where'] .= $this->get_price_filter_query_for_displayed_taxes( $max_price_filter, 'max_price', '<=' );
|
||||
$args['where'] .= $this->get_price_filter_query_for_displayed_taxes( $max_price_filter, 'min_price', '<=' );
|
||||
} else {
|
||||
$args['where'] .= $wpdb->prepare( ' AND wc_product_meta_lookup.max_price <= %f ', $max_price_filter );
|
||||
$args['where'] .= $wpdb->prepare( ' AND wc_product_meta_lookup.min_price <= %f ', $max_price_filter );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,9 +2,6 @@
|
|||
namespace Automattic\WooCommerce\StoreApi\Utilities;
|
||||
|
||||
use Automattic\WooCommerce\StoreApi\Utilities\ProductQuery;
|
||||
use Exception;
|
||||
use WP_REST_Request;
|
||||
|
||||
|
||||
/**
|
||||
* Product Query filters class.
|
||||
|
@ -114,196 +111,63 @@ class ProductQueryFilters {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get terms list for a given taxonomy.
|
||||
* Get attribute counts for the current products.
|
||||
*
|
||||
* @param string $taxonomy Taxonomy name.
|
||||
*
|
||||
* @return array
|
||||
* @param \WP_REST_Request $request The request object.
|
||||
* @param array $attributes Attributes to count, either names or ids.
|
||||
* @return array termId=>count pairs.
|
||||
*/
|
||||
public function get_terms_list( string $taxonomy ) {
|
||||
public function get_attribute_counts( $request, $attributes = [] ) {
|
||||
global $wpdb;
|
||||
|
||||
return $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT term_id as term_count_id,
|
||||
count(DISTINCT product_or_parent_id) as term_count
|
||||
FROM {$wpdb->prefix}wc_product_attributes_lookup
|
||||
WHERE taxonomy = %s
|
||||
GROUP BY term_id",
|
||||
$taxonomy
|
||||
)
|
||||
// Remove paging and sorting params from the request.
|
||||
$request->set_param( 'page', null );
|
||||
$request->set_param( 'per_page', null );
|
||||
$request->set_param( 'order', null );
|
||||
$request->set_param( 'orderby', null );
|
||||
|
||||
// Grab the request from the WP Query object, and remove SQL_CALC_FOUND_ROWS and Limits so we get a list of all products.
|
||||
$product_query = new ProductQuery();
|
||||
|
||||
add_filter( 'posts_clauses', array( $product_query, 'add_query_clauses' ), 10, 2 );
|
||||
add_filter( 'posts_pre_query', '__return_empty_array' );
|
||||
|
||||
$query_args = $product_query->prepare_objects_query( $request );
|
||||
$query_args['no_found_rows'] = true;
|
||||
$query_args['posts_per_page'] = -1;
|
||||
$query = new \WP_Query();
|
||||
$result = $query->query( $query_args );
|
||||
$product_query_sql = $query->request;
|
||||
|
||||
remove_filter( 'posts_clauses', array( $product_query, 'add_query_clauses' ), 10 );
|
||||
remove_filter( 'posts_pre_query', '__return_empty_array' );
|
||||
|
||||
if ( count( $attributes ) === count( array_filter( $attributes, 'is_numeric' ) ) ) {
|
||||
$attributes = array_map( 'wc_attribute_taxonomy_name_by_id', wp_parse_id_list( $attributes ) );
|
||||
}
|
||||
|
||||
$attributes_to_count = array_map(
|
||||
function ( $attribute ) {
|
||||
$attribute = wc_sanitize_taxonomy_name( $attribute );
|
||||
return esc_sql( $attribute );
|
||||
},
|
||||
$attributes
|
||||
);
|
||||
}
|
||||
$attributes_to_count_sql = 'AND term_taxonomy.taxonomy IN ("' . implode( '","', $attributes_to_count ) . '")';
|
||||
$attribute_count_sql = "
|
||||
SELECT COUNT( DISTINCT posts.ID ) as term_count, terms.term_id as term_count_id
|
||||
FROM {$wpdb->posts} AS posts
|
||||
INNER JOIN {$wpdb->term_relationships} AS term_relationships ON posts.ID = term_relationships.object_id
|
||||
INNER JOIN {$wpdb->term_taxonomy} AS term_taxonomy USING( term_taxonomy_id )
|
||||
INNER JOIN {$wpdb->terms} AS terms USING( term_id )
|
||||
WHERE posts.ID IN ( {$product_query_sql} )
|
||||
{$attributes_to_count_sql}
|
||||
GROUP BY terms.term_id
|
||||
";
|
||||
|
||||
/**
|
||||
* Get the empty terms list for a given taxonomy.
|
||||
*
|
||||
* @param string $taxonomy Taxonomy name.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_empty_terms_list( string $taxonomy ) {
|
||||
global $wpdb;
|
||||
$results = $wpdb->get_results( $attribute_count_sql ); // phpcs:ignore
|
||||
|
||||
return $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT DISTINCT term_id as term_count_id,
|
||||
0 as term_count
|
||||
FROM {$wpdb->prefix}wc_product_attributes_lookup
|
||||
WHERE taxonomy = %s",
|
||||
$taxonomy
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attribute and meta counts.
|
||||
*
|
||||
* @param WP_REST_Request $request Request data.
|
||||
* @param string $filtered_attribute The attribute to count.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_attribute_counts( $request, $filtered_attribute ) {
|
||||
if ( is_array( $filtered_attribute ) ) {
|
||||
wc_deprecated_argument( 'attributes', 'TBD', 'get_attribute_counts does not require an array of attributes as the second parameter anymore. Provide the filtered attribute as a string instead.' );
|
||||
|
||||
$filtered_attribute = ! empty( $filtered_attribute[0] ) ? $filtered_attribute[0] : '';
|
||||
|
||||
if ( empty( $filtered_attribute ) ) {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
|
||||
$attributes_data = $request->get_param( 'attributes' );
|
||||
$calculate_attribute_counts = $request->get_param( 'calculate_attribute_counts' );
|
||||
$min_price = $request->get_param( 'min_price' );
|
||||
$max_price = $request->get_param( 'max_price' );
|
||||
$rating = $request->get_param( 'rating' );
|
||||
$stock_status = $request->get_param( 'stock_status' );
|
||||
|
||||
$transient_key = 'wc_get_attribute_and_meta_counts_' . md5(
|
||||
wp_json_encode(
|
||||
array(
|
||||
'attributes_data' => $attributes_data,
|
||||
'calculate_attribute_counts' => $calculate_attribute_counts,
|
||||
'min_price' => $min_price,
|
||||
'max_price' => $max_price,
|
||||
'rating' => $rating,
|
||||
'stock_status' => $stock_status,
|
||||
'filtered_attribute' => $filtered_attribute,
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$cached_results = get_transient( $transient_key );
|
||||
if ( ! empty( $cached_results ) && defined( 'WP_DEBUG' ) && ! WP_DEBUG ) {
|
||||
return $cached_results;
|
||||
}
|
||||
|
||||
if ( empty( $attributes_data ) && empty( $min_price ) && empty( $max_price ) && empty( $rating ) && empty( $stock_status ) ) {
|
||||
$counts = $this->get_terms_list( $filtered_attribute );
|
||||
|
||||
return array_map( 'absint', wp_list_pluck( $counts, 'term_count', 'term_count_id' ) );
|
||||
}
|
||||
|
||||
$where_clause = '';
|
||||
if ( ! empty( $min_price ) || ! empty( $max_price ) || ! empty( $rating ) || ! empty( $stock_status ) ) {
|
||||
$product_metas = [
|
||||
'min_price' => $min_price,
|
||||
'max_price' => $max_price,
|
||||
'average_rating' => $rating,
|
||||
'stock_status' => $stock_status,
|
||||
];
|
||||
|
||||
$filtered_products_by_metas = $this->get_product_by_metas( $product_metas );
|
||||
$formatted_filtered_products_by_metas = implode( ',', array_map( 'intval', $filtered_products_by_metas ) );
|
||||
|
||||
if ( ! empty( $formatted_filtered_products_by_metas ) ) {
|
||||
if ( ! empty( $rating ) ) {
|
||||
$where_clause .= sprintf( ' AND product_attribute_lookup.product_or_parent_id IN (%1s)', $formatted_filtered_products_by_metas );
|
||||
} else {
|
||||
$where_clause .= sprintf( ' AND product_attribute_lookup.product_id IN (%1s)', $formatted_filtered_products_by_metas );
|
||||
}
|
||||
} else {
|
||||
$counts = $this->get_empty_terms_list( $filtered_attribute );
|
||||
|
||||
return array_map( 'absint', wp_list_pluck( $counts, 'term_count', 'term_count_id' ) );
|
||||
}
|
||||
}
|
||||
|
||||
$join_type = 'LEFT';
|
||||
foreach ( $attributes_data as $attribute ) {
|
||||
$filtered_terms = $attribute['slug'] ?? '';
|
||||
|
||||
if ( empty( $filtered_terms ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$taxonomy = $attribute['attribute'] ?? '';
|
||||
$term_ids = [];
|
||||
if ( in_array( $taxonomy, wc_get_attribute_taxonomy_names(), true ) ) {
|
||||
foreach ( $filtered_terms as $filtered_term ) {
|
||||
$term = get_term_by( 'slug', $filtered_term, $taxonomy );
|
||||
if ( is_object( $term ) ) {
|
||||
$term_ids[] = $term->term_id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ( empty( $term_ids ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ( $calculate_attribute_counts as $calculate_attribute_count ) {
|
||||
if ( ! isset( $calculate_attribute_count['taxonomy'] ) && ! isset( $calculate_attribute_count['query_type'] ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$query_type = $calculate_attribute_count['query_type'];
|
||||
$filtered_products_by_terms = $this->get_product_by_filtered_terms( $calculate_attribute_count['taxonomy'], $term_ids, $query_type );
|
||||
$formatted_filtered_products_by_terms = implode( ',', array_map( 'intval', $filtered_products_by_terms ) );
|
||||
|
||||
if ( ! empty( $formatted_filtered_products_by_terms ) ) {
|
||||
$where_clause .= sprintf( ' AND product_attribute_lookup.product_or_parent_id IN (%1s)', $formatted_filtered_products_by_terms );
|
||||
}
|
||||
|
||||
if ( $calculate_attribute_count['taxonomy'] === $filtered_attribute ) {
|
||||
$join_type = 'or' === $query_type ? 'LEFT' : 'INNER';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
global $wpdb;
|
||||
$counts = $wpdb->get_results(
|
||||
// phpcs:disable WordPress.DB.PreparedSQLPlaceholders.UnquotedComplexPlaceholder
|
||||
$wpdb->prepare(
|
||||
"
|
||||
SELECT attributes.term_id as term_count_id, coalesce(term_count, 0) as term_count
|
||||
FROM (SELECT DISTINCT term_id
|
||||
FROM {$wpdb->prefix}wc_product_attributes_lookup
|
||||
WHERE taxonomy = %s) as attributes %1s JOIN (
|
||||
SELECT COUNT(DISTINCT product_attribute_lookup.product_or_parent_id) as term_count, product_attribute_lookup.term_id
|
||||
FROM {$wpdb->prefix}wc_product_attributes_lookup product_attribute_lookup
|
||||
INNER JOIN {$wpdb->posts} posts
|
||||
ON posts.ID = product_attribute_lookup.product_id
|
||||
WHERE posts.post_type IN ('product', 'product_variation') AND posts.post_status = 'publish'%1s
|
||||
GROUP BY product_attribute_lookup.term_id
|
||||
) summarize
|
||||
ON attributes.term_id = summarize.term_id
|
||||
",
|
||||
$filtered_attribute,
|
||||
$join_type,
|
||||
$where_clause
|
||||
)
|
||||
);
|
||||
|
||||
// phpcs:enable
|
||||
$results = array_map( 'absint', wp_list_pluck( $counts, 'term_count', 'term_count_id' ) );
|
||||
|
||||
set_transient( $transient_key, $results, 24 * HOUR_IN_SECONDS );
|
||||
|
||||
return $results;
|
||||
return array_map( 'absint', wp_list_pluck( $results, 'term_count', 'term_count_id' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -347,139 +211,4 @@ class ProductQueryFilters {
|
|||
|
||||
return array_map( 'absint', wp_list_pluck( $results, 'product_count', 'rounded_average_rating' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets product by metas.
|
||||
*
|
||||
* @since TBD
|
||||
* @param array $metas Array of metas to query.
|
||||
* @return array $results
|
||||
*/
|
||||
public function get_product_by_metas( $metas = array() ) {
|
||||
global $wpdb;
|
||||
|
||||
if ( empty( $metas ) ) {
|
||||
return array();
|
||||
}
|
||||
|
||||
$where = array();
|
||||
$results = array();
|
||||
$params = array();
|
||||
foreach ( $metas as $column => $value ) {
|
||||
if ( empty( $value ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( 'stock_status' === $column ) {
|
||||
$stock_product_ids = array();
|
||||
foreach ( $value as $stock_status ) {
|
||||
$stock_product_ids[] = $wpdb->get_col(
|
||||
$wpdb->prepare(
|
||||
"SELECT DISTINCT product_id FROM {$wpdb->prefix}wc_product_meta_lookup WHERE stock_status = %s",
|
||||
$stock_status
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
$where[] = 'product_id IN (' . implode( ',', array_merge( ...$stock_product_ids ) ) . ')';
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( 'min_price' === $column ) {
|
||||
$where[] = "{$column} >= %d";
|
||||
$params[] = intval( $value ) / 100;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( 'max_price' === $column ) {
|
||||
$where[] = "{$column} <= %d";
|
||||
$params[] = intval( $value ) / 100;
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( 'average_rating' === $column ) {
|
||||
$where_rating = array();
|
||||
foreach ( $value as $rating ) {
|
||||
$where_rating[] = sprintf( '(average_rating >= %f - 0.5 AND average_rating < %f + 0.5)', $rating, $rating );
|
||||
}
|
||||
$where[] = '(' . implode( ' OR ', $where_rating ) . ')';
|
||||
continue;
|
||||
}
|
||||
|
||||
$where[] = sprintf( "%1s = '%s'", $column, $value );
|
||||
$params[] = $value;
|
||||
}
|
||||
|
||||
if ( ! empty( $where ) ) {
|
||||
$where_clause = implode( ' AND ', $where );
|
||||
$where_clause = sprintf( $where_clause, ...$params );
|
||||
|
||||
// phpcs:disable WordPress.DB.PreparedSQLPlaceholders.UnquotedComplexPlaceholder
|
||||
$results = $wpdb->get_col(
|
||||
$wpdb->prepare(
|
||||
"SELECT DISTINCT product_id FROM {$wpdb->prefix}wc_product_meta_lookup WHERE %1s",
|
||||
$where_clause
|
||||
)
|
||||
);
|
||||
}
|
||||
// phpcs:enable
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets product by filtered terms.
|
||||
*
|
||||
* @since TBD
|
||||
* @param string $taxonomy Taxonomy name.
|
||||
* @param array $term_ids Term IDs.
|
||||
* @param string $query_type or | and.
|
||||
* @return array Product IDs.
|
||||
*/
|
||||
public function get_product_by_filtered_terms( $taxonomy = '', $term_ids = array(), $query_type = 'or' ) {
|
||||
global $wpdb;
|
||||
|
||||
$term_count = count( $term_ids );
|
||||
$results = array();
|
||||
$term_ids = implode( ',', array_map( 'intval', $term_ids ) );
|
||||
|
||||
if ( 'or' === $query_type ) {
|
||||
$results = $wpdb->get_col(
|
||||
// phpcs:disable WordPress.DB.PreparedSQLPlaceholders.UnquotedComplexPlaceholder
|
||||
$wpdb->prepare(
|
||||
"
|
||||
SELECT DISTINCT `product_or_parent_id`
|
||||
FROM {$wpdb->prefix}wc_product_attributes_lookup
|
||||
WHERE `taxonomy` = %s
|
||||
AND `term_id` IN (%1s)
|
||||
",
|
||||
$taxonomy,
|
||||
$term_ids
|
||||
)
|
||||
// phpcs:enable
|
||||
);
|
||||
}
|
||||
|
||||
if ( 'and' === $query_type ) {
|
||||
$results = $wpdb->get_col(
|
||||
// phpcs:disable WordPress.DB.PreparedSQLPlaceholders.UnquotedComplexPlaceholder
|
||||
$wpdb->prepare(
|
||||
"
|
||||
SELECT DISTINCT `product_or_parent_id`
|
||||
FROM {$wpdb->prefix}wc_product_attributes_lookup
|
||||
WHERE `taxonomy` = %s
|
||||
AND `term_id` IN (%1s)
|
||||
GROUP BY `product_or_parent_id`
|
||||
HAVING COUNT( DISTINCT `term_id` ) >= %d
|
||||
",
|
||||
$taxonomy,
|
||||
$term_ids,
|
||||
$term_count
|
||||
)
|
||||
// phpcs:enable
|
||||
);
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -84,6 +84,7 @@ class ProductCollectionData extends ControllerTestCase {
|
|||
);
|
||||
$fixtures->get_taxonomy_and_term( $product, 'pa_size', 'large', 'large' );
|
||||
|
||||
// AND query type.
|
||||
$request = new \WP_REST_Request( 'GET', '/wc/store/v1/products/collection-data' );
|
||||
$request->set_param(
|
||||
'calculate_attribute_counts',
|
||||
|
@ -95,6 +96,30 @@ class ProductCollectionData extends ControllerTestCase {
|
|||
),
|
||||
);
|
||||
|
||||
$response = rest_get_server()->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertEquals( 200, $response->get_status() );
|
||||
$this->assertEquals( null, $data['price_range'] );
|
||||
$this->assertEquals( null, $data['rating_counts'] );
|
||||
|
||||
$this->assertIsArray( $data );
|
||||
|
||||
$this->assertTrue( property_exists( $data['attribute_counts'][0], 'term' ) );
|
||||
$this->assertTrue( property_exists( $data['attribute_counts'][0], 'count' ) );
|
||||
|
||||
// OR query type.
|
||||
$request = new \WP_REST_Request( 'GET', '/wc/store/v1/products/collection-data' );
|
||||
$request->set_param(
|
||||
'calculate_attribute_counts',
|
||||
array(
|
||||
array(
|
||||
'taxonomy' => 'pa_size',
|
||||
'query_type' => 'or',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$request->set_param(
|
||||
'attributes',
|
||||
array(
|
||||
|
@ -114,6 +139,7 @@ class ProductCollectionData extends ControllerTestCase {
|
|||
$this->assertEquals( null, $data['rating_counts'] );
|
||||
|
||||
$this->assertIsArray( $data );
|
||||
|
||||
$this->assertTrue( property_exists( $data['attribute_counts'][0], 'term' ) );
|
||||
$this->assertTrue( property_exists( $data['attribute_counts'][0], 'count' ) );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue