Commit dfe30f5d606 for woocommerce

commit dfe30f5d6069632900963aaa6f395634979fe725
Author: Seun Olorunsola <30554163+triple0t@users.noreply.github.com>
Date:   Wed Mar 4 11:33:58 2026 +0100

    Email Editor: Use configured subject for preview emails (#63504)

    * Add woocommerce_email_editor_send_preview_email_subject filter to allow customizing the preview email subject

    * Add method to update email subject for preview emails

    This commit introduces a new filter, `woocommerce_email_editor_send_preview_email_subject`, allowing customization of the email subject when sending preview emails. The method checks the post type and retrieves the appropriate subject from the registered email class, enhancing the email editor's functionality.

    * Use EmailPreview to resolve configured email subject for preview emails

diff --git a/packages/php/email-editor/README.md b/packages/php/email-editor/README.md
index 6e3cee46435..ab6f9ad546d 100644
--- a/packages/php/email-editor/README.md
+++ b/packages/php/email-editor/README.md
@@ -104,6 +104,7 @@ We may add, update and delete any of them.
 | `woocommerce_email_editor_rendering_email_context`                 | `Array` $email_context                                           | `Array` $email_context                                       | Applied during email rendering to provide context data (e.g., `recipient_email`, `user_id`, `order_id`) to block renderers.                                            |
 | `woocommerce_email_editor_send_preview_email_rendered_data`        | `string` $data Rendered email, `WP_Post` $post                   | `string` Rendered email                                      | Allows modifying the rendered email when displaying or sending it in preview                                                                                           |
 | `woocommerce_email_editor_send_preview_email_personalizer_context` | `string` $content_styles, `WP_Post` $post` $personalizer_context | `Array` Personalizer context data                            | Allows modifying the personalizer context data for the send preview email function                                                                                     |
+| `woocommerce_email_editor_send_preview_email_subject`              | `string` $subject, `WP_Post` $post                               | `string` The email subject                                   | Allows modifying the subject of the preview email before it is sent or rendered. Defaults to the post title.                                                           |
 | `woocommerce_email_editor_synced_site_styles`                      | `Array` $synced_data, `Array` $site_data                         | `Array` Modified synced data                                 | Used to filter the synced site style data before applying to email theme.                                                                                              |
 | `woocommerce_email_editor_site_style_sync_enabled`                 | `bool` $enabled                                                  | `bool`                                                       | Use to control whether site style sync functionality is enabled or disabled. Returning `false` will disable site theme sync.                                           |
 | `woocommerce_email_editor_site_theme`                              | `WP_Theme_JSON` $site_theme                                      | `WP_Theme_JSON`                                              | Modify the site theme before syncing styles to the email editor.                                                                                                       |
diff --git a/packages/php/email-editor/changelog/add-preview-email-subject-filter b/packages/php/email-editor/changelog/add-preview-email-subject-filter
new file mode 100644
index 00000000000..d7a6e8315fc
--- /dev/null
+++ b/packages/php/email-editor/changelog/add-preview-email-subject-filter
@@ -0,0 +1,4 @@
+Significance: patch
+Type: add
+
+Add woocommerce_email_editor_send_preview_email_subject filter to allow customizing the preview email subject.
diff --git a/packages/php/email-editor/src/Engine/class-send-preview-email.php b/packages/php/email-editor/src/Engine/class-send-preview-email.php
index 60ca601dc9b..7fc43a45b02 100644
--- a/packages/php/email-editor/src/Engine/class-send-preview-email.php
+++ b/packages/php/email-editor/src/Engine/class-send-preview-email.php
@@ -69,7 +69,7 @@ class Send_Preview_Email {
 		$post_id = $data['postId'];

 		$post    = $this->fetch_post( $post_id );
-		$subject = $post->post_title;
+		$subject = $this->get_preview_email_subject( $post );

 		$email_html_content = $this->render_html( $post );

@@ -83,7 +83,7 @@ class Send_Preview_Email {
 	 * @return string
 	 */
 	public function render_html( $post ): string {
-		$subject  = $post->post_title;
+		$subject  = $this->get_preview_email_subject( $post );
 		$language = get_bloginfo( 'language' );

 		// Add filter to set preview context for block renderers.
@@ -104,6 +104,25 @@ class Send_Preview_Email {
 		return $this->set_personalize_content( $rendered_data['html'] );
 	}

+	/**
+	 * Get the subject of the preview email.
+	 *
+	 * @param \WP_Post $post The WordPress post object.
+	 * @return string
+	 */
+	public function get_preview_email_subject( $post ): string {
+		/**
+		 * Filters the subject of the preview email before it is sent or rendered.
+		 *
+		 * @param string   $subject The email subject, defaults to the post title.
+		 * @param \WP_Post $post    The email post object.
+		 *
+		 * @since 2.9.0
+		 */
+		$subject = (string) apply_filters( 'woocommerce_email_editor_send_preview_email_subject', $post->post_title, $post );
+		return $subject;
+	}
+
 	/**
 	 * Add preview context to email rendering.
 	 *
diff --git a/packages/php/email-editor/tests/integration/Engine/Send_Preview_Email_Test.php b/packages/php/email-editor/tests/integration/Engine/Send_Preview_Email_Test.php
index aa38fa99a8c..d7031cdee48 100644
--- a/packages/php/email-editor/tests/integration/Engine/Send_Preview_Email_Test.php
+++ b/packages/php/email-editor/tests/integration/Engine/Send_Preview_Email_Test.php
@@ -119,6 +119,47 @@ class Send_Preview_Email_Test extends \Email_Editor_Integration_Test_Case {
 		$this->assertEquals( $mailing_status, $result );
 	}

+	/**
+	 * Test the preview email subject defaults to the post title.
+	 */
+	public function testGetPreviewEmailSubjectDefaultsToPostTitle(): void {
+		$post = $this->factory->post->create_and_get(
+			array(
+				'post_title' => 'My Email Subject',
+			)
+		);
+		$this->assertInstanceOf( \WP_Post::class, $post );
+
+		$result = $this->send_preview_email->get_preview_email_subject( $post );
+
+		$this->assertEquals( 'My Email Subject', $result );
+	}
+
+	/**
+	 * Test the preview email subject can be filtered.
+	 */
+	public function testGetPreviewEmailSubjectCanBeFiltered(): void {
+		$post = $this->factory->post->create_and_get(
+			array(
+				'post_title' => 'Original Subject',
+			)
+		);
+		$this->assertInstanceOf( \WP_Post::class, $post );
+
+		$filter = function ( $subject, $filter_post ) use ( $post ) {
+			$this->assertInstanceOf( \WP_Post::class, $filter_post );
+			$this->assertEquals( $post->ID, $filter_post->ID );
+			return 'Filtered: ' . $subject;
+		};
+		add_filter( 'woocommerce_email_editor_send_preview_email_subject', $filter, 10, 2 );
+
+		$result = $this->send_preview_email->get_preview_email_subject( $post );
+
+		$this->assertEquals( 'Filtered: Original Subject', $result );
+
+		remove_filter( 'woocommerce_email_editor_send_preview_email_subject', $filter );
+	}
+
 	/**
 	 * Test it throws an exception with invalid email
 	 */
diff --git a/plugins/woocommerce/changelog/add-preview-email-subject-filter b/plugins/woocommerce/changelog/add-preview-email-subject-filter
new file mode 100644
index 00000000000..cb63ee28c7c
--- /dev/null
+++ b/plugins/woocommerce/changelog/add-preview-email-subject-filter
@@ -0,0 +1,4 @@
+Significance: minor
+Type: enhancement
+
+Use the configured email subject from WC_Email settings when sending preview emails instead of the raw post title.
diff --git a/plugins/woocommerce/src/Internal/EmailEditor/Integration.php b/plugins/woocommerce/src/Internal/EmailEditor/Integration.php
index a13b39e18e6..bb46aeddd5a 100644
--- a/plugins/woocommerce/src/Internal/EmailEditor/Integration.php
+++ b/plugins/woocommerce/src/Internal/EmailEditor/Integration.php
@@ -139,6 +139,7 @@ class Integration {
 		add_filter( 'woocommerce_email_editor_preview_post_template_html', array( $this, 'update_preview_post_template_html_data' ), 100, 1 );
 		add_action( 'woocommerce_email_editor_send_preview_email_before_wp_mail', array( $this, 'send_preview_email_before_wp_mail' ), 10 );
 		add_action( 'woocommerce_email_editor_send_preview_email_after_wp_mail', array( $this, 'send_preview_email_after_wp_mail' ), 10 );
+		add_filter( 'woocommerce_email_editor_send_preview_email_subject', array( $this, 'update_email_subject_for_send_preview_email' ), 10, 2 );
 	}

 	/**
@@ -415,4 +416,41 @@ class Integration {
 		remove_filter( 'wp_mail_from', array( $this->wc_email_instance, 'get_from_address' ) );
 		remove_filter( 'wp_mail_from_name', array( $this->wc_email_instance, 'get_from_name' ) );
 	}
+
+	/**
+	 * Update the email subject for the send preview email.
+	 *
+	 * @param string  $subject The email subject.
+	 * @param WP_Post $post    The post object.
+	 * @return string The updated email subject.
+	 */
+	public function update_email_subject_for_send_preview_email( $subject, $post ) {
+		if ( ! $post instanceof \WP_Post || self::EMAIL_POST_TYPE !== $post->post_type ) {
+			return $subject;
+		}
+
+		$post_manager = WCTransactionalEmailPostsManager::get_instance();
+
+		$email_type_class_name = $post_manager->get_email_type_class_name_from_post_id( $post->ID );
+
+		if ( empty( $email_type_class_name ) ) {
+			return $subject;
+		}
+
+		/**
+		 * Validate the email type class name.
+		 *
+		 * @var EmailPreview $email_preview
+		 */
+		$email_preview = wc_get_container()->get( EmailPreview::class );
+
+		try {
+			$email_preview->set_email_type( $email_type_class_name );
+			return $email_preview->get_subject();
+		} catch ( \InvalidArgumentException $e ) {
+			return $subject;
+		} catch ( \Throwable $e ) {
+			return $subject;
+		}
+	}
 }