Commit 8d6e5bcbf4 for woocommerce

commit 8d6e5bcbf47d754b76cb87e9fe89378dcc0ba648
Author: Seun Olorunsola <30554163+triple0t@users.noreply.github.com>
Date:   Mon Dec 1 08:47:03 2025 +0100

    Add block email editor support for order fulfillment notification emails (#62146)

    * Opt in fulfillment emails for block email editor support.

    This will allow Woo create email posts required for the editor.

    * Add initial block email templates for customer fulfillment notifications

    This commit introduces three new email templates for customer fulfillment:
    - `customer-fulfillment-created.php` for notifying customers when their items are on the way.
    - `customer-fulfillment-deleted.php` for informing customers when a shipment has been removed.
    - `customer-fulfillment-updated.php` for updates regarding changes to shipment details.

    These templates are designed to be customizable through the WooCommerce email editor.

    * Add filter support for skipping order details in some block email content.

    This will allow extensions to skip the order details do_action hook for some of their emails

    * Add block email editor support for fulfillment email templates

    This update introduces functionality to skip order details in the block editor for fulfillment-related emails. It also adds the ability to include fulfillment details and customer information in the general block content for the created, deleted, and updated fulfillment emails. Additionally, a method for retrieving block editor email template content has been implemented for better customization.

    * Refactor fulfillment email classes to utilize a shared template for block content

    This commit removes redundant methods from the fulfillment email classes and introduces a new template file for general block content used in fulfillment emails. The changes streamline the email structure and enhance customization capabilities for created, deleted, and updated fulfillment notifications.

    * Add changelog and fix lint errors

    * coderabbit feedback

diff --git a/plugins/woocommerce/changelog/wooprd-1428-enable-block-email-support-for-other-woo-core-emails b/plugins/woocommerce/changelog/wooprd-1428-enable-block-email-support-for-other-woo-core-emails
new file mode 100644
index 0000000000..d6169ef25e
--- /dev/null
+++ b/plugins/woocommerce/changelog/wooprd-1428-enable-block-email-support-for-other-woo-core-emails
@@ -0,0 +1,4 @@
+Significance: patch
+Type: add
+
+Add block email template for Fulfillment emails.
diff --git a/plugins/woocommerce/includes/emails/class-wc-email-customer-fulfillment-created.php b/plugins/woocommerce/includes/emails/class-wc-email-customer-fulfillment-created.php
index 2dfaff7926..0046afd12c 100644
--- a/plugins/woocommerce/includes/emails/class-wc-email-customer-fulfillment-created.php
+++ b/plugins/woocommerce/includes/emails/class-wc-email-customer-fulfillment-created.php
@@ -53,6 +53,8 @@ if ( ! class_exists( 'WC_Email_Customer_Fulfillment_Created', false ) ) :
 			parent::__construct();

 			$this->description = __( 'Fulfillment created emails are sent to the customer when the merchant creates a fulfillment for the order, and marks it as fulfilled. The notification isn’t sent for draft fulfillments.', 'woocommerce' );
+
+			$this->template_block_content = 'emails/block/general-block-content-for-fulfillment-emails.php';
 		}

 		/**
@@ -146,6 +148,25 @@ if ( ! class_exists( 'WC_Email_Customer_Fulfillment_Created', false ) ) :
 			);
 		}

+		/**
+		 * Get block editor email template content.
+		 *
+		 * @return string
+		 */
+		public function get_block_editor_email_template_content() {
+			$this->maybe_init_fulfillment_for_preview( $this->object );
+			return wc_get_template_html(
+				$this->template_block_content,
+				array(
+					'order'         => $this->object,
+					'fulfillment'   => $this->fulfillment,
+					'sent_to_admin' => false,
+					'plain_text'    => false,
+					'email'         => $this,
+				)
+			);
+		}
+
 		/**
 		 * Default content to show below main email content.
 		 *
diff --git a/plugins/woocommerce/includes/emails/class-wc-email-customer-fulfillment-deleted.php b/plugins/woocommerce/includes/emails/class-wc-email-customer-fulfillment-deleted.php
index 2b9c6aceca..31233184c2 100644
--- a/plugins/woocommerce/includes/emails/class-wc-email-customer-fulfillment-deleted.php
+++ b/plugins/woocommerce/includes/emails/class-wc-email-customer-fulfillment-deleted.php
@@ -53,6 +53,8 @@ if ( ! class_exists( 'WC_Email_Customer_Fulfillment_Deleted', false ) ) :
 			parent::__construct();

 			$this->description = __( 'Fulfillment deleted emails are sent to the customer when the merchant cancels an already fulfilled fulfillment. The notification isn’t sent for draft fulfillments.', 'woocommerce' );
+
+			$this->template_block_content = 'emails/block/general-block-content-for-fulfillment-emails.php';
 		}

 		/**
@@ -146,6 +148,25 @@ if ( ! class_exists( 'WC_Email_Customer_Fulfillment_Deleted', false ) ) :
 			);
 		}

+		/**
+		 * Get block editor email template content.
+		 *
+		 * @return string
+		 */
+		public function get_block_editor_email_template_content() {
+			$this->maybe_init_fulfillment_for_preview( $this->object );
+			return wc_get_template_html(
+				$this->template_block_content,
+				array(
+					'order'         => $this->object,
+					'fulfillment'   => $this->fulfillment,
+					'sent_to_admin' => false,
+					'plain_text'    => false,
+					'email'         => $this,
+				)
+			);
+		}
+
 		/**
 		 * Default content to show below main email content.
 		 *
diff --git a/plugins/woocommerce/includes/emails/class-wc-email-customer-fulfillment-updated.php b/plugins/woocommerce/includes/emails/class-wc-email-customer-fulfillment-updated.php
index 6225d25167..8a3a7f6e6f 100644
--- a/plugins/woocommerce/includes/emails/class-wc-email-customer-fulfillment-updated.php
+++ b/plugins/woocommerce/includes/emails/class-wc-email-customer-fulfillment-updated.php
@@ -53,6 +53,8 @@ if ( ! class_exists( 'WC_Email_Customer_Fulfillment_Updated', false ) ) :
 			parent::__construct();

 			$this->description = __( 'Fulfillment updated emails are sent to the customer when the merchant updates a fulfillment for the order. The notification isn’t sent for draft fulfillments.', 'woocommerce' );
+
+			$this->template_block_content = 'emails/block/general-block-content-for-fulfillment-emails.php';
 		}

 		/**
@@ -146,6 +148,25 @@ if ( ! class_exists( 'WC_Email_Customer_Fulfillment_Updated', false ) ) :
 			);
 		}

+		/**
+		 * Get block editor email template content.
+		 *
+		 * @return string
+		 */
+		public function get_block_editor_email_template_content() {
+			$this->maybe_init_fulfillment_for_preview( $this->object );
+			return wc_get_template_html(
+				$this->template_block_content,
+				array(
+					'order'         => $this->object,
+					'fulfillment'   => $this->fulfillment,
+					'sent_to_admin' => false,
+					'plain_text'    => false,
+					'email'         => $this,
+				)
+			);
+		}
+
 		/**
 		 * Default content to show below main email content.
 		 *
diff --git a/plugins/woocommerce/src/Internal/EmailEditor/WCTransactionalEmails/WCTransactionalEmails.php b/plugins/woocommerce/src/Internal/EmailEditor/WCTransactionalEmails/WCTransactionalEmails.php
index 94ff99ca38..0079036aca 100644
--- a/plugins/woocommerce/src/Internal/EmailEditor/WCTransactionalEmails/WCTransactionalEmails.php
+++ b/plugins/woocommerce/src/Internal/EmailEditor/WCTransactionalEmails/WCTransactionalEmails.php
@@ -73,6 +73,15 @@ class WCTransactionalEmails {
 			$emails[] = 'customer_pos_refunded_order';
 		}

+		if ( FeaturesUtil::feature_is_enabled( 'fulfillments' ) ) {
+			$fulfillment_emails = array(
+				'customer_fulfillment_created',
+				'customer_fulfillment_updated',
+				'customer_fulfillment_deleted',
+			);
+			$emails             = array_merge( $emails, $fulfillment_emails );
+		}
+
 		/**
 		 * Filter the transactional emails for the block editor.
 		 *
diff --git a/plugins/woocommerce/templates/emails/block/customer-fulfillment-created.php b/plugins/woocommerce/templates/emails/block/customer-fulfillment-created.php
new file mode 100644
index 0000000000..3189b7634d
--- /dev/null
+++ b/plugins/woocommerce/templates/emails/block/customer-fulfillment-created.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Customer fulfillment created email (initial block version)
+ *
+ * This template can be overridden by editing it in the WooCommerce email editor.
+ *
+ * HOWEVER, on occasion WooCommerce will need to update template files and you
+ * (the theme developer) will need to copy the new files to your theme to
+ * maintain compatibility. We try to do this as little as possible, but it does
+ * happen. When this occurs the version of the template file will be bumped and
+ * the readme will list any important changes.
+ *
+ * @see https://woocommerce.com/document/template-structure/
+ * @package WooCommerce\Templates\Emails\Block
+ * @version 10.5.0
+ */
+
+use Automattic\WooCommerce\Internal\EmailEditor\BlockEmailRenderer;
+
+defined( 'ABSPATH' ) || exit;
+
+// phpcs:disable Squiz.PHP.EmbeddedPhp.ContentBeforeOpen -- removed to prevent empty new lines.
+// phpcs:disable Squiz.PHP.EmbeddedPhp.ContentAfterEnd -- removed to prevent empty new lines.
+?>
+
+<!-- wp:heading -->
+<h2 class="wp-block-heading"> <?php echo esc_html__( 'Your item is on the way!', 'woocommerce' ); ?> </h2>
+<!-- /wp:heading -->
+
+<!-- wp:paragraph -->
+<p><?php
+	echo esc_html__( 'Woo! Some items you purchased are being fulfilled. You can use the below information to track your shipment:', 'woocommerce' );
+?></p>
+<!-- /wp:paragraph -->
+
+<!-- wp:woocommerce/email-content {"lock":{"move":false,"remove":true}} -->
+<div class="wp-block-woocommerce-email-content"> <?php echo esc_html( BlockEmailRenderer::WOO_EMAIL_CONTENT_PLACEHOLDER ); ?> </div>
+<!-- /wp:woocommerce/email-content -->
+
+<!-- wp:paragraph -->
+<p><?php
+echo esc_html__( 'Please note that couriers may need some time to provide the latest shipping information.', 'woocommerce' );
+?></p>
+<!-- /wp:paragraph -->
diff --git a/plugins/woocommerce/templates/emails/block/customer-fulfillment-deleted.php b/plugins/woocommerce/templates/emails/block/customer-fulfillment-deleted.php
new file mode 100644
index 0000000000..c53bdd366d
--- /dev/null
+++ b/plugins/woocommerce/templates/emails/block/customer-fulfillment-deleted.php
@@ -0,0 +1,44 @@
+<?php
+/**
+ * Customer fulfillment deleted email (initial block version)
+ *
+ * This template can be overridden by editing it in the WooCommerce email editor.
+ *
+ * HOWEVER, on occasion WooCommerce will need to update template files and you
+ * (the theme developer) will need to copy the new files to your theme to
+ * maintain compatibility. We try to do this as little as possible, but it does
+ * happen. When this occurs the version of the template file will be bumped and
+ * the readme will list any important changes.
+ *
+ * @see https://woocommerce.com/document/template-structure/
+ * @package WooCommerce\Templates\Emails\Block
+ * @version 10.5.0
+ */
+
+use Automattic\WooCommerce\Internal\EmailEditor\BlockEmailRenderer;
+
+defined( 'ABSPATH' ) || exit;
+
+// phpcs:disable Squiz.PHP.EmbeddedPhp.ContentBeforeOpen -- removed to prevent empty new lines.
+// phpcs:disable Squiz.PHP.EmbeddedPhp.ContentAfterEnd -- removed to prevent empty new lines.
+?>
+
+<!-- wp:heading -->
+<h2 class="wp-block-heading"> <?php echo esc_html__( 'One of your shipments has been removed', 'woocommerce' ); ?> </h2>
+<!-- /wp:heading -->
+
+<!-- wp:paragraph -->
+<p><?php
+	echo esc_html__( 'We wanted to let you know that one of the previously fulfilled shipments from your order has been removed from our system. This may have been due to a correction or an update in our fulfillment records. Don’t worry — this won’t affect any items you’ve already received.', 'woocommerce' );
+?></p>
+<!-- /wp:paragraph -->
+
+<!-- wp:woocommerce/email-content {"lock":{"move":false,"remove":true}} -->
+<div class="wp-block-woocommerce-email-content"> <?php echo esc_html( BlockEmailRenderer::WOO_EMAIL_CONTENT_PLACEHOLDER ); ?> </div>
+<!-- /wp:woocommerce/email-content -->
+
+<!-- wp:paragraph -->
+<p><?php
+echo esc_html__( 'If you have any questions or notice anything unexpected, feel free to reach out to our support team through your account or reply to this email.', 'woocommerce' );
+?></p>
+<!-- /wp:paragraph -->
diff --git a/plugins/woocommerce/templates/emails/block/customer-fulfillment-updated.php b/plugins/woocommerce/templates/emails/block/customer-fulfillment-updated.php
new file mode 100644
index 0000000000..2071dffbe3
--- /dev/null
+++ b/plugins/woocommerce/templates/emails/block/customer-fulfillment-updated.php
@@ -0,0 +1,50 @@
+<?php
+/**
+ * Customer fulfillment updated email (initial block version)
+ *
+ * This template can be overridden by editing it in the WooCommerce email editor.
+ *
+ * HOWEVER, on occasion WooCommerce will need to update template files and you
+ * (the theme developer) will need to copy the new files to your theme to
+ * maintain compatibility. We try to do this as little as possible, but it does
+ * happen. When this occurs the version of the template file will be bumped and
+ * the readme will list any important changes.
+ *
+ * @see https://woocommerce.com/document/template-structure/
+ * @package WooCommerce\Templates\Emails\Block
+ * @version 10.5.0
+ */
+
+use Automattic\WooCommerce\Internal\EmailEditor\BlockEmailRenderer;
+
+defined( 'ABSPATH' ) || exit;
+
+// phpcs:disable Squiz.PHP.EmbeddedPhp.ContentBeforeOpen -- removed to prevent empty new lines.
+// phpcs:disable Squiz.PHP.EmbeddedPhp.ContentAfterEnd -- removed to prevent empty new lines.
+?>
+
+<!-- wp:heading -->
+<h2 class="wp-block-heading"> <?php echo esc_html__( 'Your shipment has been updated', 'woocommerce' ); ?> </h2>
+<!-- /wp:heading -->
+
+<!-- wp:paragraph -->
+<p><?php
+	echo esc_html__( 'Some details of your shipment have recently been updated. This may include tracking information, item contents, or delivery status.', 'woocommerce' );
+?></p>
+<!-- /wp:paragraph -->
+
+<!-- wp:paragraph -->
+<p><?php
+	echo esc_html__( 'Here’s the latest info we have:', 'woocommerce' );
+?></p>
+<!-- /wp:paragraph -->
+
+<!-- wp:woocommerce/email-content {"lock":{"move":false,"remove":true}} -->
+<div class="wp-block-woocommerce-email-content"> <?php echo esc_html( BlockEmailRenderer::WOO_EMAIL_CONTENT_PLACEHOLDER ); ?> </div>
+<!-- /wp:woocommerce/email-content -->
+
+<!-- wp:paragraph -->
+<p><?php
+echo esc_html__( 'If anything looks off or you have questions, feel free to contact our support team.', 'woocommerce' );
+?></p>
+<!-- /wp:paragraph -->
diff --git a/plugins/woocommerce/templates/emails/block/customer-on-hold-order.php b/plugins/woocommerce/templates/emails/block/customer-on-hold-order.php
index f4b6788b77..33fa7c2c70 100644
--- a/plugins/woocommerce/templates/emails/block/customer-on-hold-order.php
+++ b/plugins/woocommerce/templates/emails/block/customer-on-hold-order.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Customer on-hold order email (inital block version)
+ * Customer on-hold order email (initial block version)
  *
  * This template can be overridden by editing it in the WooCommerce email editor.
  *
@@ -12,7 +12,7 @@
  *
  * @see https://woocommerce.com/document/template-structure/
  * @package WooCommerce\Templates\Emails\Block
- * @version 10.2.0
+ * @version 10.5.0
  */

 use Automattic\WooCommerce\Internal\EmailEditor\BlockEmailRenderer;
diff --git a/plugins/woocommerce/templates/emails/block/customer-pos-refunded-order.php b/plugins/woocommerce/templates/emails/block/customer-pos-refunded-order.php
index e0c14fe6bb..c284dc3278 100644
--- a/plugins/woocommerce/templates/emails/block/customer-pos-refunded-order.php
+++ b/plugins/woocommerce/templates/emails/block/customer-pos-refunded-order.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Customer POS refunded order email (inital block version)
+ * Customer POS refunded order email (initial block version)
  *
  * This template can be overridden by editing it in the WooCommerce email editor.
  *
@@ -12,7 +12,7 @@
  *
  * @see https://woocommerce.com/document/template-structure/
  * @package WooCommerce\Templates\Emails\Block
- * @version 10.2.0
+ * @version 10.5.0
  */

 use Automattic\WooCommerce\Internal\EmailEditor\BlockEmailRenderer;
diff --git a/plugins/woocommerce/templates/emails/block/customer-processing-order.php b/plugins/woocommerce/templates/emails/block/customer-processing-order.php
index 85b994166d..a9ff53a551 100644
--- a/plugins/woocommerce/templates/emails/block/customer-processing-order.php
+++ b/plugins/woocommerce/templates/emails/block/customer-processing-order.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Customer processing order email (inital block version)
+ * Customer processing order email (initial block version)
  *
  * This template can be overridden by editing it in the WooCommerce email editor.
  *
@@ -12,7 +12,7 @@
  *
  * @see https://woocommerce.com/document/template-structure/
  * @package WooCommerce\Templates\Emails\Block
- * @version 10.2.0
+ * @version 10.5.0
  */

 use Automattic\WooCommerce\Internal\EmailEditor\BlockEmailRenderer;
diff --git a/plugins/woocommerce/templates/emails/block/customer-refunded-order.php b/plugins/woocommerce/templates/emails/block/customer-refunded-order.php
index 94bbe0d6b7..4d0f2444cd 100644
--- a/plugins/woocommerce/templates/emails/block/customer-refunded-order.php
+++ b/plugins/woocommerce/templates/emails/block/customer-refunded-order.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Customer refunded order email (inital block version)
+ * Customer refunded order email (initial block version)
  *
  * This template can be overridden by editing it in the WooCommerce email editor.
  *
@@ -12,7 +12,7 @@
  *
  * @see https://woocommerce.com/document/template-structure/
  * @package WooCommerce\Templates\Emails\Block
- * @version 10.2.0
+ * @version 10.5.0
  */

 use Automattic\WooCommerce\Internal\EmailEditor\BlockEmailRenderer;
diff --git a/plugins/woocommerce/templates/emails/block/customer-reset-password.php b/plugins/woocommerce/templates/emails/block/customer-reset-password.php
index ead98014bd..1f6c96384e 100644
--- a/plugins/woocommerce/templates/emails/block/customer-reset-password.php
+++ b/plugins/woocommerce/templates/emails/block/customer-reset-password.php
@@ -1,6 +1,6 @@
 <?php
 /**
- * Customer Reset Password email (inital block version)
+ * Customer Reset Password email (initial block version)
  *
  * This template can be overridden by editing it in the WooCommerce email editor.
  *
@@ -12,7 +12,7 @@
  *
  * @see https://woocommerce.com/document/template-structure/
  * @package WooCommerce\Templates\Emails\Block
- * @version 10.2.0
+ * @version 10.5.0
  */

 use Automattic\WooCommerce\Internal\EmailEditor\BlockEmailRenderer;
diff --git a/plugins/woocommerce/templates/emails/block/general-block-content-for-fulfillment-emails.php b/plugins/woocommerce/templates/emails/block/general-block-content-for-fulfillment-emails.php
new file mode 100644
index 0000000000..9d0515f44a
--- /dev/null
+++ b/plugins/woocommerce/templates/emails/block/general-block-content-for-fulfillment-emails.php
@@ -0,0 +1,63 @@
+<?php
+/**
+ * General block content for fulfillment emails
+ *
+ * Note: This template is only used in the fulfillment emails.
+ *
+ * Used to render information for the email editor WooCommerce content block (BlockEmailRenderer::WOO_EMAIL_CONTENT_PLACEHOLDER).
+ *
+ * @see https://woocommerce.com/document/template-structure/
+ * @package WooCommerce\Templates\Emails\Block
+ * @version 10.5.0
+ */
+
+defined( 'ABSPATH' ) || exit;
+
+// phpcs:disable Squiz.PHP.EmbeddedPhp.ContentBeforeOpen -- removed to prevent empty new lines.
+// phpcs:disable Squiz.PHP.EmbeddedPhp.ContentAfterEnd -- removed to prevent empty new lines.
+
+if ( ! isset( $order, $fulfillment ) ) {
+	return;
+}
+
+/**
+ * Hook for the woocommerce_email_fulfillment_details.
+ *
+ * @since 10.1.0
+ * @param WC_Order $order The order object.
+ * @param Fulfillment $fulfillment The fulfillment object.
+ * @param bool $sent_to_admin Whether the email is sent to admin.
+ * @param bool $plain_text Whether the email is plain text.
+ * @param WC_Email $email The email object.
+ *
+ * @hooked WC_Emails::fulfillment_details() Shows the fulfillment details.
+ */
+do_action( 'woocommerce_email_fulfillment_details', $order, $fulfillment, $sent_to_admin, $plain_text, $email );
+
+/**
+ * Hook for the woocommerce_email_fulfillment_meta.
+ *
+ * @param WC_Order $order The order object.
+ * @param Fulfillment $fulfillment The fulfillment object.
+ * @param bool $sent_to_admin Whether the email is sent to admin.
+ * @param bool $plain_text Whether the email is plain text.
+ * @param WC_Email $email The email object.
+ * @since 10.1.0
+ *
+ * @hooked WC_Emails::order_meta() Shows fulfillment meta data.
+ */
+do_action( 'woocommerce_email_fulfillment_meta', $order, $fulfillment, $sent_to_admin, $plain_text, $email );
+
+/**
+ * Hook for woocommerce_email_customer_details.
+ *
+ * @param WC_Order $order The order object.
+ * @param bool $sent_to_admin Whether the email is sent to admin.
+ * @param bool $plain_text Whether the email is plain text.
+ * @param WC_Email $email The email object.
+ * @since 2.5.0
+ *
+ * @hooked WC_Emails::customer_details() Shows customer details
+ * @hooked WC_Emails::email_address() Shows email address
+ */
+do_action( 'woocommerce_email_customer_details', $order, $sent_to_admin, $plain_text, $email );
diff --git a/plugins/woocommerce/templates/emails/block/general-block-email.php b/plugins/woocommerce/templates/emails/block/general-block-email.php
index d30c9f19c0..ee2a0dacdd 100644
--- a/plugins/woocommerce/templates/emails/block/general-block-email.php
+++ b/plugins/woocommerce/templates/emails/block/general-block-email.php
@@ -97,15 +97,24 @@ endif;
  * @param bool     $plain_text Whether the email is being sent as plain text.
  * @param WC_Email $email The email object.
  */
-do_action( 'woocommerce_email_general_block_email', $sent_to_admin, $plain_text, $email );
+do_action( 'woocommerce_email_general_block_content', $sent_to_admin, $plain_text, $email );

+/**
+ * Filter the list of email IDs that should not display order details.
+ *
+ * @since 10.5.0
+ * @param array $emails_without_order_details Array of email IDs that should not display order details.
+ */
+$emails_without_order_details = apply_filters( 'woocommerce_emails_general_block_content_emails_without_order_details', array() );

 $accounts_related_emails = array(
 	'customer_reset_password',
 	'customer_new_account',
 );

-if ( isset( $order ) && ! in_array( $email->id, $accounts_related_emails, true ) ) {
+$emails_without_order_details = array_merge( $emails_without_order_details ?? array(), $accounts_related_emails );
+
+if ( isset( $order ) && ! in_array( $email->id, $emails_without_order_details, true ) ) {

 	/**
 	 * Woocommerce_email_order_details