Commit 1a4ac92050 for woocommerce

commit 1a4ac920501f71c30226a034476580de88b5f75e
Author: Allison Levine <1689238+allilevine@users.noreply.github.com>
Date:   Mon Jan 5 06:44:23 2026 -0500

    Email editor: Add text alignment for has-text-align-* classes. (#62588)

    * Email editor: Add text alignment for has-text-align-* classes.

    * Add changefile(s) from automation for the following project(s): packages/php/email-editor

    * Fix missing new line in changelog.

    * Add changefile(s) from automation for the following project(s): packages/php/email-editor

    ---------

    Co-authored-by: github-actions <github-actions@github.com>
    Co-authored-by: Tony Arcangelini <33258733+arcangelini@users.noreply.github.com>

diff --git a/packages/php/email-editor/changelog/62588-add-text-alignment-by-class b/packages/php/email-editor/changelog/62588-add-text-alignment-by-class
new file mode 100644
index 0000000000..8e8c379ea7
--- /dev/null
+++ b/packages/php/email-editor/changelog/62588-add-text-alignment-by-class
@@ -0,0 +1,4 @@
+Significance: minor
+Type: add
+
+Email editor: Add text alignment for has-text-align-* classes.
\ No newline at end of file
diff --git a/packages/php/email-editor/src/Integrations/Core/Renderer/Blocks/class-text.php b/packages/php/email-editor/src/Integrations/Core/Renderer/Blocks/class-text.php
index ce2102bb92..9e5a7b59f6 100644
--- a/packages/php/email-editor/src/Integrations/Core/Renderer/Blocks/class-text.php
+++ b/packages/php/email-editor/src/Integrations/Core/Renderer/Blocks/class-text.php
@@ -30,20 +30,32 @@ class Text extends Abstract_Block_Renderer {
 			return '';
 		}

-		$block_content    = $this->adjustStyleAttribute( $block_content );
-		$block_attributes = wp_parse_args(
+		$block_content        = $this->adjustStyleAttribute( $block_content );
+		$block_attributes     = wp_parse_args(
 			$parsed_block['attrs'] ?? array(),
 			array(
 				'textAlign' => 'left',
 				'style'     => array(),
 			)
 		);
-		$html             = new \WP_HTML_Tag_Processor( $block_content );
-		$classes          = 'email-text-block';
+		$html                 = new \WP_HTML_Tag_Processor( $block_content );
+		$classes              = 'email-text-block';
+		$alignment_from_class = null;
 		if ( $html->next_tag() ) {
 			/** @var string $block_classes */ // phpcs:ignore Generic.Commenting.DocComment.MissingShort -- used for phpstan
 			$block_classes = $html->get_attribute( 'class' ) ?? '';
 			$classes      .= ' ' . $block_classes;
+
+			// Extract text alignment from has-text-align-* classes before they're potentially modified.
+			$class_attr = (string) $block_classes;
+			if ( false !== strpos( $class_attr, 'has-text-align-center' ) ) {
+				$alignment_from_class = 'center';
+			} elseif ( false !== strpos( $class_attr, 'has-text-align-right' ) ) {
+				$alignment_from_class = 'right';
+			} elseif ( false !== strpos( $class_attr, 'has-text-align-left' ) ) {
+				$alignment_from_class = 'left';
+			}
+
 			// remove has-background to prevent double padding applied for wrapper and inner element.
 			$block_classes = str_replace( 'has-background', '', $block_classes );
 			// remove border related classes because we handle border on wrapping table cell.
@@ -69,6 +81,8 @@ class Text extends Abstract_Block_Renderer {
 			$additional_styles['text-align'] = $parsed_block['attrs']['textAlign'];
 		} elseif ( in_array( $parsed_block['attrs']['align'] ?? null, array( 'left', 'center', 'right' ), true ) ) {
 			$additional_styles['text-align'] = $parsed_block['attrs']['align'];
+		} elseif ( null !== $alignment_from_class ) {
+			$additional_styles['text-align'] = $alignment_from_class;
 		}

 		$block_styles = Styles_Helper::extend_block_styles( $block_styles, $additional_styles );
diff --git a/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Heading_Test.php b/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Heading_Test.php
index 17e2f1cef1..9d0263bd0e 100644
--- a/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Heading_Test.php
+++ b/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Heading_Test.php
@@ -165,4 +165,60 @@ class Heading_Test extends \Email_Editor_Integration_Test_Case {
 		$this->assertStringContainsString( 'font-size:28px;', $rendered );
 		$this->assertStringContainsString( 'font-weight:900;', $rendered );
 	}
+
+	/**
+	 * Test it extracts alignment from has-text-align-center class when no textAlign attribute is set
+	 */
+	public function testItExtractsAlignmentFromHasTextAlignCenterClass(): void {
+		$parsed_heading = $this->parsed_heading;
+		// Ensure no textAlign or align attributes are set.
+		unset( $parsed_heading['attrs']['textAlign'] );
+		unset( $parsed_heading['attrs']['align'] );
+
+		$content                        = '<h1 class="has-text-align-center">Centered heading</h1>';
+		$parsed_heading['innerHTML']    = $content;
+		$parsed_heading['innerContent'] = array( $content );
+
+		$rendered = $this->heading_renderer->render( $content, $parsed_heading, $this->rendering_context );
+		$this->assertStringContainsString( 'text-align:center;', $rendered );
+		$this->assertStringContainsString( 'align="center"', $rendered );
+	}
+
+	/**
+	 * Test it extracts alignment from has-text-align-right class when no textAlign attribute is set
+	 */
+	public function testItExtractsAlignmentFromHasTextAlignRightClass(): void {
+		$parsed_heading = $this->parsed_heading;
+		// Ensure no textAlign or align attributes are set.
+		unset( $parsed_heading['attrs']['textAlign'] );
+		unset( $parsed_heading['attrs']['align'] );
+
+		$content                        = '<h1 class="has-text-align-right">Right aligned heading</h1>';
+		$parsed_heading['innerHTML']    = $content;
+		$parsed_heading['innerContent'] = array( $content );
+
+		$rendered = $this->heading_renderer->render( $content, $parsed_heading, $this->rendering_context );
+		$this->assertStringContainsString( 'text-align:right;', $rendered );
+		$this->assertStringContainsString( 'align="right"', $rendered );
+	}
+
+	/**
+	 * Test it prioritizes textAlign attribute over has-text-align-* class
+	 */
+	public function testItPrioritizesTextAlignAttributeOverClass(): void {
+		$parsed_heading                       = $this->parsed_heading;
+		$parsed_heading['attrs']['textAlign'] = 'right';
+		unset( $parsed_heading['attrs']['align'] );
+
+		$content                        = '<h1 class="has-text-align-center">Heading with center class but right attribute</h1>';
+		$parsed_heading['innerHTML']    = $content;
+		$parsed_heading['innerContent'] = array( $content );
+
+		$rendered = $this->heading_renderer->render( $content, $parsed_heading, $this->rendering_context );
+		// Should use the attribute, not the class.
+		$this->assertStringContainsString( 'text-align:right;', $rendered );
+		$this->assertStringContainsString( 'align="right"', $rendered );
+		$this->assertStringNotContainsString( 'text-align:center;', $rendered );
+		$this->assertStringNotContainsString( 'align="center"', $rendered );
+	}
 }
diff --git a/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Paragraph_Test.php b/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Paragraph_Test.php
index c94e30e0c6..982b73089d 100644
--- a/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Paragraph_Test.php
+++ b/packages/php/email-editor/tests/integration/Integrations/Core/Renderer/Blocks/Paragraph_Test.php
@@ -172,4 +172,78 @@ class Paragraph_Test extends \Email_Editor_Integration_Test_Case {
 		$rendered = $this->paragraph_renderer->render( '<p>Lorem Ipsum</p>', $parsed_paragraph, $this->rendering_context );
 		$this->assertStringContainsString( 'color:#ff0000;', $rendered );
 	}
+
+	/**
+	 * Test it extracts alignment from has-text-align-center class when no textAlign attribute is set
+	 */
+	public function testItExtractsAlignmentFromHasTextAlignCenterClass(): void {
+		$parsed_paragraph = $this->parsed_paragraph;
+		// Ensure no textAlign or align attributes are set.
+		unset( $parsed_paragraph['attrs']['textAlign'] );
+		unset( $parsed_paragraph['attrs']['align'] );
+
+		$content                          = '<p class="has-text-align-center">Centered text</p>';
+		$parsed_paragraph['innerHTML']    = $content;
+		$parsed_paragraph['innerContent'] = array( $content );
+
+		$rendered = $this->paragraph_renderer->render( $content, $parsed_paragraph, $this->rendering_context );
+		$this->assertStringContainsString( 'text-align:center;', $rendered );
+		$this->assertStringContainsString( 'align="center"', $rendered );
+	}
+
+	/**
+	 * Test it extracts alignment from has-text-align-right class when no textAlign attribute is set
+	 */
+	public function testItExtractsAlignmentFromHasTextAlignRightClass(): void {
+		$parsed_paragraph = $this->parsed_paragraph;
+		// Ensure no textAlign or align attributes are set.
+		unset( $parsed_paragraph['attrs']['textAlign'] );
+		unset( $parsed_paragraph['attrs']['align'] );
+
+		$content                          = '<p class="has-text-align-right">Right aligned text</p>';
+		$parsed_paragraph['innerHTML']    = $content;
+		$parsed_paragraph['innerContent'] = array( $content );
+
+		$rendered = $this->paragraph_renderer->render( $content, $parsed_paragraph, $this->rendering_context );
+		$this->assertStringContainsString( 'text-align:right;', $rendered );
+		$this->assertStringContainsString( 'align="right"', $rendered );
+	}
+
+	/**
+	 * Test it extracts alignment from has-text-align-left class when no textAlign attribute is set
+	 */
+	public function testItExtractsAlignmentFromHasTextAlignLeftClass(): void {
+		$parsed_paragraph = $this->parsed_paragraph;
+		// Ensure no textAlign or align attributes are set.
+		unset( $parsed_paragraph['attrs']['textAlign'] );
+		unset( $parsed_paragraph['attrs']['align'] );
+
+		$content                          = '<p class="has-text-align-left">Left aligned text</p>';
+		$parsed_paragraph['innerHTML']    = $content;
+		$parsed_paragraph['innerContent'] = array( $content );
+
+		$rendered = $this->paragraph_renderer->render( $content, $parsed_paragraph, $this->rendering_context );
+		$this->assertStringContainsString( 'text-align:left;', $rendered );
+		$this->assertStringContainsString( 'align="left"', $rendered );
+	}
+
+	/**
+	 * Test it prioritizes textAlign attribute over has-text-align-* class
+	 */
+	public function testItPrioritizesTextAlignAttributeOverClass(): void {
+		$parsed_paragraph                       = $this->parsed_paragraph;
+		$parsed_paragraph['attrs']['textAlign'] = 'right';
+		unset( $parsed_paragraph['attrs']['align'] );
+
+		$content                          = '<p class="has-text-align-center">Text with center class but right attribute</p>';
+		$parsed_paragraph['innerHTML']    = $content;
+		$parsed_paragraph['innerContent'] = array( $content );
+
+		$rendered = $this->paragraph_renderer->render( $content, $parsed_paragraph, $this->rendering_context );
+		// Should use the attribute, not the class.
+		$this->assertStringContainsString( 'text-align:right;', $rendered );
+		$this->assertStringContainsString( 'align="right"', $rendered );
+		$this->assertStringNotContainsString( 'text-align:center;', $rendered );
+		$this->assertStringNotContainsString( 'align="center"', $rendered );
+	}
 }