Automattic\WooCommerce\Internal\OrderReviews
ItemEligibility::preload_for_items
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() 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;
}
}
}
}