Commit cce6d253980 for woocommerce

commit cce6d253980cd74827a5b854fead5e3cf56c3db3
Author: Chris Lilitsas <1105590+xristos3490@users.noreply.github.com>
Date:   Tue Oct 13 12:54:21 2026 +0300

    Fix the back-in-stock notification email preview fatal error (#69501)

    * fix: Return a string permalink so the back-in-stock email preview loads

    * fix: Return no permalink for ID-less products instead of the global post

diff --git a/plugins/woocommerce/changelog/fix-wooplug-7913-bis-email-preview-fatal b/plugins/woocommerce/changelog/fix-wooplug-7913-bis-email-preview-fatal
new file mode 100644
index 00000000000..df4f4da5101
--- /dev/null
+++ b/plugins/woocommerce/changelog/fix-wooplug-7913-bis-email-preview-fatal
@@ -0,0 +1,4 @@
+Significance: patch
+Type: fix
+
+Fix the back-in-stock notification email preview, which failed to load in the email settings.
diff --git a/plugins/woocommerce/src/Internal/StockNotifications/Notification.php b/plugins/woocommerce/src/Internal/StockNotifications/Notification.php
index d4f41a52260..31bbdd3c90f 100644
--- a/plugins/woocommerce/src/Internal/StockNotifications/Notification.php
+++ b/plugins/woocommerce/src/Internal/StockNotifications/Notification.php
@@ -427,13 +427,13 @@ class Notification extends \WC_Data {
 	public function get_product_permalink() {

 		$product = $this->get_product();
-		if ( ! $product ) {
+		if ( ! $product || ! $product->get_id() ) {
 			return '';
 		}

 		$posted_attributes = $this->get_meta( 'posted_attributes' );
 		if ( ! $product instanceof \WC_Product_Variation || empty( $posted_attributes ) || ! is_array( $posted_attributes ) ) {
-			return $product->get_permalink();
+			return (string) $product->get_permalink();
 		}

 		// Posted attributes hold only the values chosen for "Any" attributes, so merge them over the variation's own attributes to build a complete link.
@@ -441,7 +441,7 @@ class Notification extends \WC_Data {
 		$variation_attributes = $product->get_variation_attributes();
 		$attributes           = array_merge( $variation_attributes, array_intersect_key( $posted_attributes, $variation_attributes ) );

-		return $product->get_permalink( array( 'variation' => $attributes ) );
+		return (string) $product->get_permalink( array( 'variation' => $attributes ) );
 	}

 	/**
diff --git a/plugins/woocommerce/tests/php/src/Internal/StockNotifications/NotificationTests.php b/plugins/woocommerce/tests/php/src/Internal/StockNotifications/NotificationTests.php
index 625438c767e..cd986de2bf0 100644
--- a/plugins/woocommerce/tests/php/src/Internal/StockNotifications/NotificationTests.php
+++ b/plugins/woocommerce/tests/php/src/Internal/StockNotifications/NotificationTests.php
@@ -5,6 +5,7 @@ namespace Automattic\WooCommerce\Tests\Internal\StockNotifications;

 use Automattic\WooCommerce\Internal\StockNotifications\Notification;
 use Automattic\WooCommerce\Internal\StockNotifications\Config;
+use Automattic\WooCommerce\Internal\StockNotifications\Factory;

 /**
  * NotificationTests data tests.
@@ -147,6 +148,21 @@ class NotificationTests extends \WC_Unit_Test_Case {
 		$this->assertSame( $expected, $notification->get_product_permalink(), 'Permalink should carry the variation attribute and the posted "Any" attribute, and nothing else' );
 	}

+	/**
+	 * @testdox Should return an empty string for an unsaved product, as used by the email preview, instead of linking to the global post.
+	 */
+	public function test_get_product_permalink_for_unsaved_product(): void {
+		$notification = Factory::create_dummy_notification();
+		// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- get_permalink( 0 ) falls back to the global post.
+		$GLOBALS['post'] = get_post( $this->factory->post->create() );
+
+		try {
+			$this->assertSame( '', $notification->get_product_permalink() );
+		} finally {
+			unset( $GLOBALS['post'] );
+		}
+	}
+
 	/**
 	 * Test the get_product_name method.
 	 */