Commit a3c89c6c403 for woocommerce
commit a3c89c6c4037718b297acd876d2d35513c1e3600
Author: Vladimir Reznichenko <kalessil@gmail.com>
Date: Wed Oct 7 11:50:33 2026 +0200
[Performance] Consolidate verified review meta population across core workflows (#68044)
Populate verified-owner review meta consistently across all review submission workflows.
---------
Co-authored-by: Marcin Dudek <marcin.dudek.dev@gmail.com>
diff --git a/plugins/woocommerce/changelog/review-verified-owner-meta-backfill b/plugins/woocommerce/changelog/review-verified-owner-meta-backfill
new file mode 100644
index 00000000000..8d5f1d1af8c
--- /dev/null
+++ b/plugins/woocommerce/changelog/review-verified-owner-meta-backfill
@@ -0,0 +1,4 @@
+Significance: minor
+Type: performance
+
+Populate verified-owner review meta consistently across all review submission workflows.
diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php
index fda59f3e98e..9eaa821ac3b 100644
--- a/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php
+++ b/plugins/woocommerce/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller.php
@@ -319,7 +319,8 @@ class WC_REST_Product_Reviews_V1_Controller extends WC_REST_Controller {
return new WP_Error( 'rest_product_review_failed_create', __( 'Creating product review failed.', 'woocommerce' ), array( 'status' => 500 ) );
}
- update_comment_meta( $product_review_id, 'rating', ( ! empty( $request['rating'] ) ? $request['rating'] : '0' ) );
+ update_comment_meta( $product_review_id, 'rating', ! empty( $request['rating'] ) ? $request['rating'] : '0' );
+ wc_review_is_from_verified_owner( $product_review_id );
$product_review = get_comment( $product_review_id );
diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller.php
index f959dcc559e..168880ad192 100644
--- a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller.php
+++ b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller.php
@@ -471,9 +471,10 @@ class WC_REST_Product_Reviews_Controller extends WC_REST_Controller {
}
update_comment_meta( $review_id, 'rating', ! empty( $request['rating'] ) ? $request['rating'] : '0' );
-
if ( isset( $request['verified'] ) && ! empty( $request['verified'] ) ) {
update_comment_meta( $review_id, 'verified', $request['verified'] );
+ } else {
+ wc_review_is_from_verified_owner( $review_id );
}
$review = get_comment( $review_id );
diff --git a/plugins/woocommerce/templates/single-product/review-meta.php b/plugins/woocommerce/templates/single-product/review-meta.php
index 653e9d478f0..438b026e1a9 100644
--- a/plugins/woocommerce/templates/single-product/review-meta.php
+++ b/plugins/woocommerce/templates/single-product/review-meta.php
@@ -12,13 +12,12 @@
*
* @see https://woocommerce.com/document/template-structure/
* @package WooCommerce\Templates
- * @version 3.4.0
+ * @version 11.3.0
*/
defined( 'ABSPATH' ) || exit;
global $comment;
-$verified = wc_review_is_from_verified_owner( $comment->comment_ID );
if ( '0' === $comment->comment_approved ) { ?>
@@ -33,7 +32,7 @@ if ( '0' === $comment->comment_approved ) { ?>
<p class="meta">
<strong class="woocommerce-review__author"><?php comment_author(); ?> </strong>
<?php
- if ( 'yes' === get_option( 'woocommerce_review_rating_verification_label' ) && $verified ) {
+ if ( 'yes' === get_option( 'woocommerce_review_rating_verification_label' ) && wc_review_is_from_verified_owner( $comment->comment_ID ) ) {
echo '<em class="woocommerce-review__verified verified">(' . esc_attr__( 'verified owner', 'woocommerce' ) . ')</em> ';
}
diff --git a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller-tests.php b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller-tests.php
index 7ff1a113223..b8009dfd31c 100644
--- a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller-tests.php
+++ b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version1/class-wc-rest-product-reviews-v1-controller-tests.php
@@ -674,6 +674,36 @@ class WC_REST_Product_Reviews_V1_Controller_Tests extends WC_Unit_Test_Case {
$this->assertSame( 0, (int) get_post( $source_id )->comment_count );
}
+ /**
+ * @testdox Creating a review eagerly populates the verified-owner meta at creation time, not lazily during response preparation.
+ */
+ public function test_create_item_populates_verified_meta(): void {
+ $product = ProductHelper::create_simple_product();
+ $order = OrderHelper::create_order( 0, $product );
+ $order->set_billing_email( 'jane.smith@example.org' );
+ $order->set_status( 'completed' );
+ $order->save();
+
+ // Stub prepare_item_for_response so it cannot backfill the meta as a side effect.
+ $sut = new class() extends WC_REST_Product_Reviews_V1_Controller {
+ public function prepare_item_for_response( $review, $request ) { // phpcs:ignore Squiz.Commenting.FunctionComment.Missing
+ return rest_ensure_response( array( 'id' => (int) $review->comment_ID ) );
+ }
+ };
+
+ $request = new WP_REST_Request( 'POST', '/wc/v1/products/' . $product->get_id() . '/reviews' );
+ $request->set_param( 'product_id', $product->get_id() );
+ $request->set_param( 'review', 'Great product, would buy again.' );
+ $request->set_param( 'name', 'Jane Smith' );
+ $request->set_param( 'email', 'jane.smith@example.org' );
+ $request->set_param( 'rating', 5 );
+
+ $response = $sut->create_item( $request );
+
+ $this->assertSame( 201, $response->get_status() );
+ $this->assertSame( '1', get_comment_meta( $response->get_data()['id'], 'verified', true ), 'The verified meta must be populated eagerly at creation time.' );
+ }
+
/**
* Creates a product review through the controller.
*
diff --git a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version2/class-wc-rest-product-reviews-v2-controller-tests.php b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version2/class-wc-rest-product-reviews-v2-controller-tests.php
index 967732f2281..2000d4c7de7 100644
--- a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version2/class-wc-rest-product-reviews-v2-controller-tests.php
+++ b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version2/class-wc-rest-product-reviews-v2-controller-tests.php
@@ -1,5 +1,6 @@
<?php
+use Automattic\WooCommerce\RestApi\UnitTests\Helpers\OrderHelper;
use Automattic\WooCommerce\RestApi\UnitTests\Helpers\ProductHelper;
/**
@@ -86,6 +87,36 @@ class WC_REST_Product_Reviews_V2_Controller_Test extends WC_REST_Unit_Test_case
$this->assertSame( 3, (int) get_comment_meta( $review_id, 'rating', true ) );
}
+ /**
+ * @testdox Creating a review eagerly populates the verified-owner meta at creation time, not lazily during response preparation.
+ */
+ public function test_create_item_populates_verified_meta(): void {
+ $product = ProductHelper::create_simple_product();
+ $order = OrderHelper::create_order( 0, $product );
+ $order->set_billing_email( 'jane.smith@example.org' );
+ $order->set_status( 'completed' );
+ $order->save();
+
+ // Stub prepare_item_for_response so it cannot backfill the meta as a side effect.
+ $sut = new class() extends WC_REST_Product_Reviews_V2_Controller {
+ public function prepare_item_for_response( $review, $request ) { // phpcs:ignore Squiz.Commenting.FunctionComment.Missing
+ return rest_ensure_response( array( 'id' => (int) $review->comment_ID ) );
+ }
+ };
+
+ $request = new WP_REST_Request( 'POST', '/wc/v2/products/' . $product->get_id() . '/reviews' );
+ $request->set_param( 'product_id', $product->get_id() );
+ $request->set_param( 'review', 'Great product, would buy again.' );
+ $request->set_param( 'name', 'Jane Smith' );
+ $request->set_param( 'email', 'jane.smith@example.org' );
+ $request->set_param( 'rating', 5 );
+
+ $response = $sut->create_item( $request );
+
+ $this->assertSame( 201, $response->get_status() );
+ $this->assertSame( '1', get_comment_meta( $response->get_data()['id'], 'verified', true ), 'The verified meta must be populated eagerly at creation time.' );
+ }
+
/**
* @testdox Creating a review as a shop manager strips markup that user role cannot post.
*/
diff --git a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller-tests.php b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller-tests.php
index 90ea473cdd8..75f7762bfa7 100644
--- a/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller-tests.php
+++ b/plugins/woocommerce/tests/php/includes/rest-api/Controllers/Version3/class-wc-rest-product-reviews-controller-tests.php
@@ -593,6 +593,47 @@ class WC_REST_Product_Reviews_Controller_Tests extends WC_REST_Unit_Test_Case {
$this->assertEquals( 4, $destination->get_average_rating() );
}
+ /**
+ * @testdox Creating a review eagerly populates the verified-owner meta at creation time, not lazily during response preparation.
+ * @testWith [false]
+ * [true]
+ *
+ * @param bool $include_verified Whether to include the verified parameter in the request.
+ */
+ public function test_create_item_populates_verified_meta( bool $include_verified ): void {
+ $product = ProductHelper::create_simple_product();
+ $order = OrderHelper::create_order( 0, $product );
+ $order->set_billing_email( 'jane.smith@example.org' );
+ $order->set_status( 'completed' );
+ $order->save();
+
+ // Stub prepare_item_for_response so it cannot backfill the meta as a side effect.
+ $sut = new class() extends WC_REST_Product_Reviews_Controller {
+ public function prepare_item_for_response( $review, $request ) { // phpcs:ignore Squiz.Commenting.FunctionComment.Missing
+ return rest_ensure_response( array( 'id' => (int) $review->comment_ID ) );
+ }
+ };
+
+ $body = array(
+ 'product_id' => $product->get_id(),
+ 'review' => $include_verified ? 'Verified by the caller.' : 'Great product, would buy again.',
+ 'reviewer' => 'Jane Smith',
+ 'reviewer_email' => 'jane.smith@example.org',
+ 'rating' => 5,
+ );
+ if ( $include_verified ) {
+ $body['verified'] = true;
+ }
+
+ $request = new WP_REST_Request( 'POST', '/wc/v3/products/reviews' );
+ $request->set_body_params( $body );
+
+ $response = $sut->create_item( $request );
+
+ $this->assertSame( 201, $response->get_status() );
+ $this->assertSame( '1', get_comment_meta( $response->get_data()['id'], 'verified', true ), 'The verified meta must be populated eagerly at creation time.' );
+ }
+
/**
* Creates two products and a review that can be moved between them.
*