Automattic\WooCommerce\Internal\OrderReviews

ItemEligibility::preload_for_itemspublic staticWC 10.8.0

Pre-fill the per-request review cache for a set of items in one query.

Call this from the template before iterating items so each subsequent decide() / prefill_for_item() call hits the cache instead of running its own get_comments()

Method of the class: ItemEligibility{}

No Hooks.

Returns

null. Nothing (null).

Usage

$result = ItemEligibility::preload_for_items( $items, $order ): void;
$items(iterable<WC_Order_Item_Product|mixed>) (required)
Order line items.
$order(WC_Order) (required)
Order being reviewed.

Changelog

Since 10.8.0 Introduced.

ItemEligibility::preload_for_items() code WC 10.9.4

public static function preload_for_items( iterable $items, WC_Order $order ): void {
	$email    = $order->get_billing_email();
	$order_id = $order->get_id();
	if ( '' === $email || $order_id <= 0 ) {
		return;
	}

	$preload_key = $order_id . '|' . $email;
	if ( isset( self::$preloaded[ $preload_key ] ) ) {
		return;
	}

	$product_ids = array();
	$slots       = array();
	foreach ( $items as $item ) {
		if ( $item instanceof WC_Order_Item_Product ) {
			$pid = (int) $item->get_product_id();
			$vid = (int) $item->get_variation_id();
			if ( $pid > 0 ) {
				$product_ids[ $pid ]                                       = $pid;
				$slots[ self::cache_key( $order_id, $pid, $vid, $email ) ] = true;
			}
		}
	}

	if ( empty( $product_ids ) ) {
		return;
	}

	self::$preloaded[ $preload_key ] = true;

	// Default every (product, variation) slot to null so subsequent reads don't re-query.
	foreach ( $slots as $slot_key => $_ ) {
		self::$review_cache[ $slot_key ] = null;
	}

	// Scope to this order's reviews only: a customer who buys the same
	// product on a later order shouldn't see their old review here.
	$comments = get_comments(
		array(
			'post__in'           => array_values( $product_ids ),
			'author_email'       => $email,
			'type'               => 'review',
			'status'             => 'approve',
			'include_unapproved' => array( $email ),
			'orderby'            => 'comment_date_gmt',
			'order'              => 'DESC',
			'meta_query'         => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query -- bounded by post__in + author_email.
				array(
					'key'   => self::ORDER_META_KEY,
					'value' => (string) $order_id,
				),
			),
		)
	);

	if ( is_array( $comments ) ) {
		foreach ( $comments as $comment ) {
			if ( ! $comment instanceof WP_Comment ) {
				continue;
			}
			$vid = (int) get_comment_meta( (int) $comment->comment_ID, self::VARIATION_META_KEY, true );
			$key = self::cache_key( $order_id, (int) $comment->comment_post_ID, $vid, $email );
			if ( isset( $slots[ $key ] ) && null === self::$review_cache[ $key ] ) {
				self::$review_cache[ $key ] = $comment;
			}
		}
	}
}