Commit 19edd98fc66 for woocommerce

commit 19edd98fc66e873e267b7c8c4651658babcac423
Author: Karol Manijak <20098064+kmanijak@users.noreply.github.com>
Date:   Tue Jun 16 05:24:01 2026 +0200

    Restore get_images()/get_image() REST controller signatures to avoid fatal (#65713)

    * Restore get_images() and get_image() REST controller signatures

    * Add changelog entry for get_images signature fix

    * fix: remove shared method, accept duplication

    ---------

    Co-authored-by: Tung Du <dinhtungdu@gmail.com>

diff --git a/plugins/woocommerce/changelog/fix-64009-get-images-signature-bc b/plugins/woocommerce/changelog/fix-64009-get-images-signature-bc
new file mode 100644
index 00000000000..e048e0a13d5
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-64009-get-images-signature-bc
@@ -0,0 +1,5 @@
+Significance: patch
+Type: fix
+Comment: Follow-up to unreleased #64009: restore the original get_images()/get_image() signatures on product REST controllers so third-party subclasses do not fatal on PHP 8; the image_size parameter is now read from the current request.
+
+
diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php
index 51ec47470de..f7d36f6d057 100644
--- a/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php
+++ b/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php
@@ -296,6 +296,9 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr
 	 * @return WP_REST_Response
 	 */
 	public function prepare_object_for_response( $object, $request ) {
+		// @phpstan-ignore-next-line property.notFound (Deliberately dynamic to avoid adding inherited state that can fatal subclasses.)
+		$this->request = $request;
+
 		$data = array(
 			'id'                    => $object->get_id(),
 			'date_created'          => wc_rest_prepare_date_response( $object->get_date_created(), false ),
@@ -336,7 +339,7 @@ class WC_REST_Product_Variations_V2_Controller extends WC_REST_Products_V2_Contr
 			),
 			'shipping_class'        => $object->get_shipping_class(),
 			'shipping_class_id'     => $object->get_shipping_class_id(),
-			'image'                 => current( $this->get_images( $object, $request['image_size'] ?? 'full' ) ),
+			'image'                 => current( $this->get_images( $object ) ),
 			'attributes'            => $this->get_attributes( $object ),
 			'menu_order'            => $object->get_menu_order(),
 			'meta_data'             => $object->get_meta_data(),
diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php
index 77b6348c31e..66d114d0f59 100644
--- a/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php
+++ b/plugins/woocommerce/includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php
@@ -290,7 +290,8 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller {
 	 * @return WP_REST_Response
 	 */
 	public function prepare_object_for_response( $object, $request ) {
-		$context       = ! empty( $request['context'] ) ? $request['context'] : 'view';
+		$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
+		// @phpstan-ignore-next-line property.notFound (Deliberately dynamic to avoid adding inherited state that can fatal subclasses.)
 		$this->request = $request;

 		$data = $this->prepare_object_for_response_core( $object, $request, $context );
@@ -523,11 +524,13 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller {
 	 * Get the images for a product or product variation.
 	 *
 	 * @param WC_Product|WC_Product_Variation $product Product instance.
-	 * @param string                          $image_size WordPress registered image size. Default 'full'.
 	 *
 	 * @return array
 	 */
-	protected function get_images( $product, $image_size = 'full' ) {
+	protected function get_images( $product ) {
+		$image_size = $this->request['image_size'] ?? 'full';
+		$image_size = is_string( $image_size ) && '' !== $image_size ? sanitize_text_field( $image_size ) : 'full';
+
 		$images         = array();
 		$attachment_ids = array();

@@ -1012,7 +1015,7 @@ class WC_REST_Products_V2_Controller extends WC_REST_CRUD_Controller {
 					$base_data['tags'] = $this->get_taxonomy_terms( $product, 'tag' );
 					break;
 				case 'images':
-					$base_data['images'] = $this->get_images( $product, $request['image_size'] ?? 'full' );
+					$base_data['images'] = $this->get_images( $product );
 					break;
 				case 'attributes':
 					$base_data['attributes'] = $this->get_attributes( $product );
diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php
index 5013c1a6423..d53dad3015e 100644
--- a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php
+++ b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-product-variations-controller.php
@@ -112,6 +112,9 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V
 	 * @return WP_REST_Response
 	 */
 	public function prepare_object_for_response( $object, $request ) {
+		// @phpstan-ignore-next-line property.notFound (Deliberately dynamic to avoid adding inherited state that can fatal subclasses.)
+		$this->request = $request;
+
 		$context = ! empty( $request['context'] ) ? $request['context'] : 'view';
 		$data    = array(
 			'id'                    => $object->get_id(),
@@ -156,7 +159,7 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V
 			),
 			'shipping_class'        => $object->get_shipping_class(),
 			'shipping_class_id'     => $object->get_shipping_class_id(),
-			'image'                 => $this->get_image( $object, $context, isset( $request['image_size'] ) ? $request['image_size'] : 'full' ),
+			'image'                 => $this->get_image( $object, $context ),
 			'gallery_image_ids'     => $object instanceof WC_Product ? array_map( 'intval', $object->get_gallery_image_ids() ) : array(),
 			'attributes'            => $this->get_attributes( $object ),
 			'menu_order'            => $object->get_menu_order(),
@@ -448,16 +451,18 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V
 	/**
 	 * Get the image for a product variation.
 	 *
-	 * @param WC_Product_Variation $variation  Variation data.
-	 * @param string               $context    Context of the request: 'view' or 'edit'.
-	 * @param string               $image_size Optional. WordPress registered image size to use for the image src. Default 'full'.
+	 * @param WC_Product_Variation $variation Variation data.
+	 * @param string               $context   Context of the request: 'view' or 'edit'.
 	 * @return array
 	 */
-	protected function get_image( $variation, $context = 'view', $image_size = 'full' ) {
+	protected function get_image( $variation, $context = 'view' ) {
 		if ( ! $variation->get_image_id( $context ) ) {
 			return;
 		}

+		$image_size = $this->request['image_size'] ?? 'full';
+		$image_size = is_string( $image_size ) && '' !== $image_size ? sanitize_text_field( $image_size ) : 'full';
+
 		$attachment_id   = $variation->get_image_id();
 		$attachment_post = get_post( $attachment_id );
 		if ( is_null( $attachment_post ) ) {
diff --git a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php
index 59353f4afa8..cd2e44c5207 100644
--- a/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php
+++ b/plugins/woocommerce/includes/rest-api/Controllers/Version3/class-wc-rest-products-controller.php
@@ -161,11 +161,13 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller {
 	/**
 	 * Get the images for a product or product variation.
 	 *
-	 * @param WC_Product|WC_Product_Variation $product     Product instance.
-	 * @param string                          $image_size  Image size to use. Default 'full'.
+	 * @param WC_Product|WC_Product_Variation $product Product instance.
 	 * @return array
 	 */
-	protected function get_images( $product, $image_size = 'full' ) {
+	protected function get_images( $product ) {
+		$image_size = $this->request['image_size'] ?? 'full';
+		$image_size = is_string( $image_size ) && '' !== $image_size ? sanitize_text_field( $image_size ) : 'full';
+
 		$images         = array();
 		$attachment_ids = array();

diff --git a/plugins/woocommerce/phpstan-baseline.neon b/plugins/woocommerce/phpstan-baseline.neon
index 009b1629e1f..b6e12167b47 100644
--- a/plugins/woocommerce/phpstan-baseline.neon
+++ b/plugins/woocommerce/phpstan-baseline.neon
@@ -26988,12 +26988,6 @@ parameters:
 			count: 3
 			path: includes/rest-api/Controllers/Version2/class-wc-rest-product-variations-v2-controller.php

-		-
-			message: '#^Access to an undefined property WC_REST_Products_V2_Controller\:\:\$request\.$#'
-			identifier: property.notFound
-			count: 1
-			path: includes/rest-api/Controllers/Version2/class-wc-rest-products-v2-controller.php
-
 		-
 			message: '#^Call to an undefined method WC_Data\:\:get_children\(\)\.$#'
 			identifier: method.notFound
diff --git a/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Products/Controller.php b/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Products/Controller.php
index 6c6b8cd1ce4..ab241c7ae89 100644
--- a/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Products/Controller.php
+++ b/plugins/woocommerce/src/Internal/RestApi/Routes/V4/Products/Controller.php
@@ -277,10 +277,12 @@ class Controller extends WC_REST_Products_V2_Controller {
 	 * Get the images for a product or product variation.
 	 *
 	 * @param WC_Product|WC_Product_Variation $product Product instance.
-	 * @param string                          $image_size Image size to use for the src. Default 'full'.
 	 * @return array
 	 */
-	protected function get_images( $product, $image_size = 'full' ) {
+	protected function get_images( $product ) {
+		$image_size = $this->request['image_size'] ?? 'full';
+		$image_size = is_string( $image_size ) && '' !== $image_size ? sanitize_text_field( $image_size ) : 'full';
+
 		$images         = array();
 		$attachment_ids = array();