Commit e637747f189 for woocommerce

commit e637747f1894b48804639649ce6aadfba5dc89c6
Author: Mike Jolley <mike.jolley@me.com>
Date:   Fri Mar 13 11:10:08 2026 +0000

    Performance: Prime product caches and add targetHints in REST API v4 orders (#63654)

    Add targetHints and prime product caches in REST API v4 orders endpoint

    Adds targetHints to self links so clients know allowed HTTP methods
    without an OPTIONS request. Primes product post caches before order
    serialization to avoid N+1 queries when resolving line item products.

    Extracted from #63440 for smaller review scope.

    Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>

diff --git a/plugins/woocommerce/changelog/rest-api-v4-orders-cache-priming b/plugins/woocommerce/changelog/rest-api-v4-orders-cache-priming
new file mode 100644
index 00000000000..864fc9ef16a
--- /dev/null
+++ b/plugins/woocommerce/changelog/rest-api-v4-orders-cache-priming
@@ -0,0 +1,4 @@
+Significance: minor
+Type: performance
+
+Prime product caches and add targetHints to REST API v4 orders endpoint to reduce N+1 queries during serialization.
diff --git a/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Orders/Controller.php b/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Orders/Controller.php
index c98e63e4c87..e05b1503d89 100644
--- a/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Orders/Controller.php
+++ b/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Orders/Controller.php
@@ -202,7 +202,8 @@ class Controller extends AbstractController {
 	protected function prepare_links( $item, WP_REST_Request $request, WP_REST_Response $response ): array {
 		$links = array(
 			'self'            => array(
-				'href' => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->get_id() ) ),
+				'href'        => rest_url( sprintf( '/%s/%s/%d', $this->namespace, $this->rest_base, $item->get_id() ) ),
+				'targetHints' => array( 'allow' => current_user_can( 'edit_shop_orders' ) ? array( 'GET', 'PUT', 'POST', 'PATCH', 'DELETE' ) : array( 'GET' ) ),
 			),
 			'collection'      => array(
 				'href' => rest_url( sprintf( '/%s/%s', $this->namespace, $this->rest_base ) ),
@@ -306,6 +307,21 @@ class Controller extends AbstractController {
 		$results    = $this->collection_query->get_query_results( $query_args, $request );
 		$items      = array();

+		// Prime product caches to avoid N+1 queries during serialization.
+		$product_ids = array();
+		foreach ( $results['results'] as $order ) {
+			foreach ( $order->get_items( 'line_item' ) as $item ) {
+				if ( $item instanceof \WC_Order_Item_Product ) {
+					$product_ids[] = $item->get_product_id();
+					$product_ids[] = $item->get_variation_id();
+				}
+			}
+		}
+		$product_ids = array_unique( array_filter( $product_ids ) );
+		if ( ! empty( $product_ids ) ) {
+			_prime_post_caches( $product_ids, true, true );
+		}
+
 		foreach ( $results['results'] as $result ) {
 			$items[] = $this->prepare_response_for_collection( $this->prepare_item_for_response( $result, $request ) );
 		}