Commit b43204ff518 for woocommerce

commit b43204ff518586354d886257994dbe01297e3375
Author: Defyn <99234555+Defyn-Digital@users.noreply.github.com>
Date:   Tue Oct 20 19:34:26 2026 +0545

    Fix/39380 undeprecate min max price meta query (#69740)

    * Restore wc_get_min_max_price_meta_query() as a non-deprecated function

    The products and variations REST controllers still call this function for
    the min_price and max_price filters, so every filtered request logged the
    3.6 deprecation notice. Move it to wc-product-functions.php without the
    deprecation call, keep the woocommerce_get_min_max_price_meta_query filter
    unchanged, and widen the docblock type to accept WP_REST_Request, which
    resolves four PHPStan baseline entries.

    * Add changelog entry for min/max price meta query fix

diff --git a/plugins/woocommerce/changelog/39380-undeprecate-min-max-price-meta-query b/plugins/woocommerce/changelog/39380-undeprecate-min-max-price-meta-query
new file mode 100644
index 00000000000..004b50b3c70
--- /dev/null
+++ b/plugins/woocommerce/changelog/39380-undeprecate-min-max-price-meta-query
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Stop the products REST API logging a deprecation notice when filtering by min_price or max_price.
diff --git a/plugins/woocommerce/includes/wc-deprecated-functions.php b/plugins/woocommerce/includes/wc-deprecated-functions.php
index 02b280d5ad4..627c73ca24b 100644
--- a/plugins/woocommerce/includes/wc-deprecated-functions.php
+++ b/plugins/woocommerce/includes/wc-deprecated-functions.php
@@ -1113,32 +1113,6 @@ function wc_get_core_supported_themes() {
 	return array( 'twentyseventeen', 'twentysixteen', 'twentyfifteen', 'twentyfourteen', 'twentythirteen', 'twentyeleven', 'twentytwelve', 'twentyten' );
 }

-/**
- * Get min/max price meta query args.
- *
- * @deprecated 3.6.0
- * @since 3.0.0
- * @param array $args Min price and max price arguments.
- * @return array
- */
-function wc_get_min_max_price_meta_query( $args ) {
-	wc_deprecated_function( 'wc_get_min_max_price_meta_query()', '3.6' );
-
-	$current_min_price = isset( $args['min_price'] ) ? floatval( $args['min_price'] ) : 0;
-	$current_max_price = isset( $args['max_price'] ) ? floatval( $args['max_price'] ) : PHP_INT_MAX;
-
-	return apply_filters(
-		'woocommerce_get_min_max_price_meta_query',
-		array(
-			'key'     => '_price',
-			'value'   => array( $current_min_price, $current_max_price ),
-			'compare' => 'BETWEEN',
-			'type'    => 'DECIMAL(10,' . wc_get_price_decimals() . ')',
-		),
-		$args
-	);
-}
-
 /**
  * When a term is split, ensure meta data maintained.
  *
diff --git a/plugins/woocommerce/includes/wc-product-functions.php b/plugins/woocommerce/includes/wc-product-functions.php
index 02c7514eca5..4dac815d335 100644
--- a/plugins/woocommerce/includes/wc-product-functions.php
+++ b/plugins/woocommerce/includes/wc-product-functions.php
@@ -2142,6 +2142,40 @@ function wc_products_array_orderby_price( $a, $b ) {
 	return ( $a->get_price() < $b->get_price() ) ? -1 : 1;
 }

+/**
+ * Get min/max price meta query args for the `_price` meta key.
+ *
+ * Deprecated in 3.6.0 and restored in 11.3.0, because the REST API products and
+ * variations controllers still use it for the min_price and max_price filters.
+ *
+ * @since 3.0.0
+ * @param array|WP_REST_Request<array<string, mixed>> $args Min price and max price arguments.
+ * @return array
+ */
+function wc_get_min_max_price_meta_query( $args ) {
+	$current_min_price = isset( $args['min_price'] ) ? floatval( $args['min_price'] ) : 0;
+	$current_max_price = isset( $args['max_price'] ) ? floatval( $args['max_price'] ) : PHP_INT_MAX;
+
+	/**
+	 * Filters the meta query used to match products by price.
+	 *
+	 * @since 3.0.0
+	 *
+	 * @param array                                       $meta_query Meta query args for the `_price` meta key.
+	 * @param array|WP_REST_Request<array<string, mixed>> $args       Min price and max price arguments.
+	 */
+	return apply_filters(
+		'woocommerce_get_min_max_price_meta_query',
+		array(
+			'key'     => '_price',
+			'value'   => array( $current_min_price, $current_max_price ),
+			'compare' => 'BETWEEN',
+			'type'    => 'DECIMAL(10,' . wc_get_price_decimals() . ')',
+		),
+		$args
+	);
+}
+
 /**
  * Queue a product for syncing at the end of the request.
  *
diff --git a/plugins/woocommerce/phpstan-baseline.neon b/plugins/woocommerce/phpstan-baseline.neon
index a41a215fc95..dbd35c83077 100644
--- a/plugins/woocommerce/phpstan-baseline.neon
+++ b/plugins/woocommerce/phpstan-baseline.neon
@@ -26550,12 +26550,6 @@ parameters:
 			count: 1
 			path: includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php

-		-
-			message: '#^Parameter \#1 \$args of function wc_get_min_max_price_meta_query expects array, WP_REST_Request given\.$#'
-			identifier: argument.type
-			count: 1
-			path: includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php
-
 		-
 			message: '#^Parameter \#1 \$date of function wc_rest_prepare_date_response expects string\|WC_DateTime\|null, int\<1, max\> given\.$#'
 			identifier: argument.type
@@ -29253,12 +29247,6 @@ parameters:
 			count: 1
 			path: includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php

-		-
-			message: '#^Parameter \#1 \$args of function wc_get_min_max_price_meta_query expects array, WP_REST_Request given\.$#'
-			identifier: argument.type
-			count: 1
-			path: includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php
-
 		-
 			message: '#^Parameter \#1 \$date of function wc_rest_prepare_date_response expects string\|WC_DateTime\|null, int\|false given\.$#'
 			identifier: argument.type
@@ -29547,12 +29535,6 @@ parameters:
 			count: 1
 			path: includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php

-		-
-			message: '#^Parameter \#1 \$args of function wc_get_min_max_price_meta_query expects array, WP_REST_Request given\.$#'
-			identifier: argument.type
-			count: 1
-			path: includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php
-
 		-
 			message: '#^Parameter \#1 \$array_arg of function current expects array\|object, list\<bool\|int\|string\>\|false given\.$#'
 			identifier: argument.type
@@ -63732,12 +63714,6 @@ parameters:
 			count: 1
 			path: src/Internal/RestApi/Routes/V4/Products/Controller.php

-		-
-			message: '#^Parameter \#1 \$args of function wc_get_min_max_price_meta_query expects array, WP_REST_Request given\.$#'
-			identifier: argument.type
-			count: 1
-			path: src/Internal/RestApi/Routes/V4/Products/Controller.php
-
 		-
 			message: '#^Parameter \#1 \$array_arg of function current expects array\|object, list\<bool\|int\|string\>\|false given\.$#'
 			identifier: argument.type
diff --git a/plugins/woocommerce/tests/legacy/unit-tests/product/functions.php b/plugins/woocommerce/tests/legacy/unit-tests/product/functions.php
index f4b29bef240..67d9eb9c706 100644
--- a/plugins/woocommerce/tests/legacy/unit-tests/product/functions.php
+++ b/plugins/woocommerce/tests/legacy/unit-tests/product/functions.php
@@ -1148,9 +1148,7 @@ class WC_Tests_Product_Functions extends WC_Unit_Test_Case {
 	}

 	/**
-	 * Test wc_get_min_max_price_meta_query()
-	 *
-	 * @expectedDeprecated wc_get_min_max_price_meta_query()
+	 * @testdox wc_get_min_max_price_meta_query() builds a _price meta query without a deprecation notice.
 	 */
 	public function test_wc_get_min_max_price_meta_query() {
 		$meta_query = wc_get_min_max_price_meta_query(
diff --git a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller-tests.php b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller-tests.php
index c4aa6f4b00b..ccd73a6a10c 100644
--- a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller-tests.php
+++ b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller-tests.php
@@ -385,6 +385,53 @@ class WC_REST_Products_Controller_Tests extends WC_Unit_Test_Case {
 		}
 	}

+	/**
+	 * @testdox The min_price and max_price parameters filter products by price without a deprecation notice.
+	 *
+	 * @testWith [{"min_price": "30"}, ["expensive"]]
+	 *           [{"max_price": "30"}, ["cheap"]]
+	 *           [{"min_price": "15", "max_price": "25"}, ["cheap"]]
+	 *           [{"min_price": "60"}, []]
+	 *
+	 * @param array    $params   Price filter query params.
+	 * @param string[] $expected Keys of the products expected in the response.
+	 */
+	public function test_products_filter_by_min_and_max_price( array $params, array $expected ): void {
+		$products = array(
+			'cheap'     => WC_Helper_Product::create_simple_product( true, array( 'regular_price' => 20 ) ),
+			'expensive' => WC_Helper_Product::create_simple_product( true, array( 'regular_price' => 50 ) ),
+		);
+
+		$product_ids = array_map(
+			static function ( WC_Product $product ): int {
+				return $product->get_id();
+			},
+			$products
+		);
+
+		$request = new WP_REST_Request( 'GET', '/wc/v3/products' );
+		$request->set_query_params(
+			array_merge(
+				$params,
+				array(
+					'include' => array_values( $product_ids ),
+					'orderby' => 'id',
+					'order'   => 'asc',
+				)
+			)
+		);
+		$response = $this->server->dispatch( $request );
+
+		$expected_ids = array_map(
+			static function ( string $key ) use ( $product_ids ): int {
+				return $product_ids[ $key ];
+			},
+			$expected
+		);
+		$this->assertSame( 200, $response->get_status() );
+		$this->assertSame( $expected_ids, wp_list_pluck( $response->get_data(), 'id' ), 'Price filter returned the wrong products' );
+	}
+
 	/**
 	 * Test that the `search_sku` parameter does partial matching in the product SKU, but not the name.
 	 *