Commit 3d5bffea942 for woocommerce

commit 3d5bffea942833b2d6effeb99b33efa1c131872f
Author: Ricardo Sawir <37329575+sawirricardo@users.noreply.github.com>
Date:   Thu Jul 9 15:39:34 2026 +0700

    Fix PHP 8.5+ deprecation notices from null script handle in register_chunk_translations() (#66197)

    * Skip chunk translation registration when block has no front-end script handle

    * Add changefile(s) from automation for the following project(s): woocommerce

    * Remove manual changelog entry (auto-generated from PR)

    * Add unit tests for register_chunk_translations script handle guard

    * Update changelog entry to reference PHP 8.5+

    * Deduplicate anonymous test block classes in AbstractBlockTest

    * Rework AbstractBlock tests to mock the asset API and update PHPStan baseline

    - Assert register_script() is called (or not) on a mocked Api instead of
      checking wp_script_is(), since register_chunk_translations() deregisters
      the chunk script before returning.
    - Remove the now-resolved wp_add_inline_script null-handle entry from the
      PHPStan baseline.

    * Apply suggestion from @ralucaStan

    * Add changefile(s) from automation for the following project(s): woocommerce

    ---------

    Co-authored-by: woocommercebot <woocommercebot@users.noreply.github.com>
    Co-authored-by: Raluca Stan <ralucastn@gmail.com>

diff --git a/plugins/woocommerce/changelog/66197-fix-coming-soon-null-script-handle-deprecation b/plugins/woocommerce/changelog/66197-fix-coming-soon-null-script-handle-deprecation
new file mode 100644
index 00000000000..9f273d930dd
--- /dev/null
+++ b/plugins/woocommerce/changelog/66197-fix-coming-soon-null-script-handle-deprecation
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix PHP 8.5+ deprecation notices when a block without a front-end script (e.g. Coming Soon) registers chunk translations with a null script handle.
\ No newline at end of file
diff --git a/plugins/woocommerce/phpstan-baseline.neon b/plugins/woocommerce/phpstan-baseline.neon
index aac84ee53f7..8228d25c3aa 100644
--- a/plugins/woocommerce/phpstan-baseline.neon
+++ b/plugins/woocommerce/phpstan-baseline.neon
@@ -49719,12 +49719,6 @@ parameters:
 			count: 1
 			path: src/Blocks/BlockTypes/AbstractBlock.php

-		-
-			message: '#^Parameter \#1 \$handle of function wp_add_inline_script expects string, array\|string\|null given\.$#'
-			identifier: argument.type
-			count: 1
-			path: src/Blocks/BlockTypes/AbstractBlock.php
-
 		-
 			message: '#^Parameter \#1 \$handle of function wp_enqueue_script expects string, array\|string\|null given\.$#'
 			identifier: argument.type
diff --git a/plugins/woocommerce/src/Blocks/BlockTypes/AbstractBlock.php b/plugins/woocommerce/src/Blocks/BlockTypes/AbstractBlock.php
index 066bbd08478..3b76c0849b7 100644
--- a/plugins/woocommerce/src/Blocks/BlockTypes/AbstractBlock.php
+++ b/plugins/woocommerce/src/Blocks/BlockTypes/AbstractBlock.php
@@ -184,11 +184,15 @@ abstract class AbstractBlock {
 	 * @param string[] $chunks Array of chunk names.
 	 */
 	protected function register_chunk_translations( $chunks ) {
+		$script_handle = $this->get_block_type_script( 'handle' );
+		if ( ! is_string( $script_handle ) || '' === $script_handle ) {
+			return;
+		}
 		foreach ( $chunks as $chunk ) {
 			$handle = 'wc-blocks-' . $chunk . '-chunk';
 			$this->asset_api->register_script( $handle, $this->asset_api->get_block_asset_build_path( $chunk ), [], true );
 			wp_add_inline_script(
-				$this->get_block_type_script( 'handle' ),
+				$script_handle,
 				wp_scripts()->print_translations( $handle, false ),
 				'before'
 			);
diff --git a/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/AbstractBlockTest.php b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/AbstractBlockTest.php
new file mode 100644
index 00000000000..3e2261f7983
--- /dev/null
+++ b/plugins/woocommerce/tests/php/src/Blocks/BlockTypes/AbstractBlockTest.php
@@ -0,0 +1,106 @@
+<?php
+declare( strict_types = 1 );
+
+namespace Automattic\WooCommerce\Tests\Blocks\BlockTypes;
+
+use Automattic\WooCommerce\Blocks\Assets\Api;
+use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry;
+use Automattic\WooCommerce\Blocks\BlockTypes\AbstractBlock;
+use Automattic\WooCommerce\Blocks\Integrations\IntegrationRegistry;
+use Automattic\WooCommerce\Blocks\Package;
+use WC_Unit_Test_Case;
+
+/**
+ * Tests for the AbstractBlock class.
+ */
+class AbstractBlockTest extends WC_Unit_Test_Case {
+
+	/**
+	 * Create a testable AbstractBlock instance with a mocked asset API.
+	 *
+	 * @param Api  $asset_api Mocked asset API.
+	 * @param bool $with_script_handle Whether the block has a front-end script handle.
+	 * @return AbstractBlock
+	 */
+	private function create_block( Api $asset_api, bool $with_script_handle ): AbstractBlock {
+		$asset_data_registry = Package::container()->get( AssetDataRegistry::class );
+
+		return new class( $asset_api, $asset_data_registry, new IntegrationRegistry(), 'test-block', $with_script_handle ) extends AbstractBlock {
+			/**
+			 * Whether the block has a front-end script handle.
+			 *
+			 * @var bool
+			 */
+			private $with_script_handle;
+
+			/**
+			 * Constructor.
+			 *
+			 * @param Api                 $asset_api Instance of the asset API.
+			 * @param AssetDataRegistry   $asset_data_registry Instance of the asset data registry.
+			 * @param IntegrationRegistry $integration_registry Instance of the integration registry.
+			 * @param string              $block_name Block name.
+			 * @param bool                $with_script_handle Whether the block has a front-end script handle.
+			 */
+			public function __construct( $asset_api, $asset_data_registry, $integration_registry, $block_name, bool $with_script_handle ) {
+				$this->with_script_handle = $with_script_handle;
+				parent::__construct( $asset_api, $asset_data_registry, $integration_registry, $block_name );
+			}
+
+			/**
+			 * Skip block registration in tests.
+			 */
+			protected function register_block_type() {}
+
+			/**
+			 * Blocks without a front-end script (e.g. Coming Soon) return null.
+			 *
+			 * @param string $key Data to get, or default to everything.
+			 * @return array|string|null
+			 */
+			protected function get_block_type_script( $key = null ) {
+				return $this->with_script_handle ? parent::get_block_type_script( $key ) : null;
+			}
+
+			/**
+			 * Public wrapper for register_chunk_translations.
+			 *
+			 * @param string[] $chunks Array of chunk names.
+			 */
+			public function call_register_chunk_translations( $chunks ) {
+				$this->register_chunk_translations( $chunks );
+			}
+		};
+	}
+
+	/**
+	 * @testdox Should not register chunk scripts when the block has no front-end script handle.
+	 */
+	public function test_register_chunk_translations_skips_blocks_without_script_handle(): void {
+		$asset_api = $this->createMock( Api::class );
+		$asset_api->expects( $this->never() )->method( 'register_script' );
+
+		$block = $this->create_block( $asset_api, false );
+
+		$block->call_register_chunk_translations( array( 'test-chunk' ) );
+	}
+
+	/**
+	 * @testdox Should register chunk scripts when the block has a front-end script handle.
+	 */
+	public function test_register_chunk_translations_registers_chunks_for_blocks_with_script_handle(): void {
+		$asset_api = $this->createMock( Api::class );
+		$asset_api->method( 'get_block_asset_build_path' )->willReturnCallback(
+			function ( $filename ) {
+				return "assets/client/blocks/{$filename}.js";
+			}
+		);
+		$asset_api->expects( $this->once() )
+			->method( 'register_script' )
+			->with( 'wc-blocks-test-chunk-chunk', 'assets/client/blocks/test-chunk.js', array(), true );
+
+		$block = $this->create_block( $asset_api, true );
+
+		$block->call_register_chunk_translations( array( 'test-chunk' ) );
+	}
+}