Product Collection: add price sorting options (#51670)
Co-authored-by: Manish Menaria <the.manish.menaria@gmail.com>
This commit is contained in:
parent
98053269ac
commit
870111d8af
|
@ -37,6 +37,14 @@ const orderOptions = [
|
|||
label: __( 'Oldest to newest', 'woocommerce' ),
|
||||
value: 'date/asc',
|
||||
},
|
||||
{
|
||||
label: __( 'Price, high to low', 'woocommerce' ),
|
||||
value: 'price/desc',
|
||||
},
|
||||
{
|
||||
label: __( 'Price, low to high', 'woocommerce' ),
|
||||
value: 'price/asc',
|
||||
},
|
||||
{
|
||||
value: 'popularity/desc',
|
||||
label: __( 'Best Selling', 'woocommerce' ),
|
||||
|
|
|
@ -144,6 +144,7 @@ export type TProductCollectionOrderBy =
|
|||
| 'date'
|
||||
| 'title'
|
||||
| 'popularity'
|
||||
| 'price'
|
||||
| 'rating';
|
||||
|
||||
export type ProductCollectionSetAttributes = (
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
Product Collection: add sorting options by price.
|
|
@ -53,7 +53,7 @@ class ProductCollection extends AbstractBlock {
|
|||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $custom_order_opts = array( 'popularity', 'rating', 'post__in' );
|
||||
protected $custom_order_opts = array( 'popularity', 'rating', 'post__in', 'price' );
|
||||
|
||||
|
||||
/**
|
||||
|
@ -706,7 +706,7 @@ class ProductCollection extends AbstractBlock {
|
|||
return $this->get_preview_query_args( $collection_args, $query, $request );
|
||||
}
|
||||
|
||||
$orderby = $request->get_param( 'orderBy' );
|
||||
$orderby = $request->get_param( 'orderby' );
|
||||
$on_sale = $request->get_param( 'woocommerceOnSale' ) === 'true';
|
||||
$stock_status = $request->get_param( 'woocommerceStockStatus' );
|
||||
$product_attributes = $request->get_param( 'woocommerceAttributes' );
|
||||
|
@ -1056,6 +1056,14 @@ class ProductCollection extends AbstractBlock {
|
|||
return array( 'orderby' => $orderby );
|
||||
}
|
||||
|
||||
if ( 'price' === $orderby ) {
|
||||
add_filter( 'posts_clauses', array( $this, 'add_price_sorting_posts_clauses' ), 10, 2 );
|
||||
return array(
|
||||
'isProductCollection' => true,
|
||||
'orderby' => $orderby,
|
||||
);
|
||||
}
|
||||
|
||||
$meta_keys = array(
|
||||
'popularity' => 'total_sales',
|
||||
'rating' => '_wc_average_rating',
|
||||
|
@ -1729,6 +1737,36 @@ class ProductCollection extends AbstractBlock {
|
|||
return $clauses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add the `posts_clauses` filter to add price-based sorting
|
||||
*
|
||||
* @param array $clauses The list of clauses for the query.
|
||||
* @param WP_Query $query The WP_Query instance.
|
||||
* @return array Modified list of clauses.
|
||||
*/
|
||||
public function add_price_sorting_posts_clauses( $clauses, $query ) {
|
||||
$query_vars = $query->query_vars;
|
||||
$is_product_collection_block = $query_vars['isProductCollection'] ?? false;
|
||||
|
||||
if ( ! $is_product_collection_block ) {
|
||||
return $clauses;
|
||||
}
|
||||
|
||||
$orderby = $query_vars['orderby'] ?? null;
|
||||
if ( 'price' !== $orderby ) {
|
||||
return $clauses;
|
||||
}
|
||||
|
||||
$clauses['join'] = $this->append_product_sorting_table_join( $clauses['join'] );
|
||||
$is_ascending_order = 'asc' === strtolower( $query_vars['order'] ?? 'desc' );
|
||||
|
||||
$clauses['orderby'] = $is_ascending_order ?
|
||||
'wc_product_meta_lookup.min_price ASC, wc_product_meta_lookup.product_id ASC' :
|
||||
'wc_product_meta_lookup.max_price DESC, wc_product_meta_lookup.product_id DESC';
|
||||
|
||||
return $clauses;
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if price filters need adjustment based on the tax display settings.
|
||||
*
|
||||
|
@ -1964,7 +2002,7 @@ class ProductCollection extends AbstractBlock {
|
|||
$product->get_upsell_ids()
|
||||
);
|
||||
},
|
||||
[]
|
||||
array()
|
||||
);
|
||||
|
||||
// Remove duplicates and product references. We don't want to display
|
||||
|
|
|
@ -1220,4 +1220,24 @@ class ProductCollection extends \WP_UnitTestCase {
|
|||
$this->assertEqualsCanonicalizing( $expected_product_ids, $result_frontend['post__in'] );
|
||||
$this->assertEqualsCanonicalizing( $expected_product_ids, $result_editor['post__in'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test the add_price_sorting_posts_clauses method.
|
||||
*/
|
||||
public function test_add_price_sorting_posts_clauses() {
|
||||
$parsed_block = $this->get_base_parsed_block();
|
||||
$parsed_block['attrs']['query']['orderBy'] = 'price';
|
||||
|
||||
$parsed_block['attrs']['query']['order'] = 'asc';
|
||||
$merged_query = $this->initialize_merged_query( $parsed_block );
|
||||
$query = new WP_Query( $merged_query );
|
||||
|
||||
$this->assertStringContainsString( 'wc_product_meta_lookup.min_price ASC', $query->request );
|
||||
|
||||
$parsed_block['attrs']['query']['order'] = 'desc';
|
||||
$merged_query = $this->initialize_merged_query( $parsed_block );
|
||||
$query = new WP_Query( $merged_query );
|
||||
|
||||
$this->assertStringContainsString( 'wc_product_meta_lookup.max_price DESC', $query->request );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue