EmailPatterns
10 months ago
EmailTemplates
2 months ago
PersonalizationTags
3 months ago
WCTransactionalEmails
4 weeks ago
BlockEmailRenderer.php
7 months ago
EmailApiController.php
4 weeks ago
Integration.php
4 weeks ago
Logger.php
10 months ago
Package.php
1 year ago
PageRenderer.php
10 months ago
PersonalizationTagManager.php
1 year ago
TransactionalEmailPersonalizer.php
4 months ago
WooContentProcessor.php
2 months ago
WooContentProcessor.php
183 lines
| 1 | <?php |
| 2 | declare( strict_types=1 ); |
| 3 | |
| 4 | namespace Automattic\WooCommerce\Internal\EmailEditor; |
| 5 | |
| 6 | use Automattic\WooCommerce\EmailEditor\Email_Css_Inliner; |
| 7 | use Automattic\WooCommerce\EmailEditor\Email_Editor_Container; |
| 8 | use Automattic\WooCommerce\EmailEditor\Engine\Theme_Controller; |
| 9 | |
| 10 | /** |
| 11 | * Class responsible for extracting the main content from a WC_Email object. |
| 12 | */ |
| 13 | class WooContentProcessor { |
| 14 | |
| 15 | /** |
| 16 | * Email theme controller |
| 17 | * We use it to get email CSS. |
| 18 | * |
| 19 | * @var Theme_Controller |
| 20 | */ |
| 21 | private $theme_controller; |
| 22 | |
| 23 | /** |
| 24 | * CSS inliner |
| 25 | * |
| 26 | * @var Email_Css_Inliner |
| 27 | */ |
| 28 | private $css_inliner; |
| 29 | |
| 30 | /** |
| 31 | * Constructor |
| 32 | */ |
| 33 | public function __construct() { |
| 34 | $this->theme_controller = Email_Editor_Container::container()->get( Theme_Controller::class ); |
| 35 | $this->css_inliner = new Email_Css_Inliner(); |
| 36 | } |
| 37 | |
| 38 | /** |
| 39 | * Get the WooCommerce content excluding headers and footers. |
| 40 | * |
| 41 | * @param \WC_Email $wc_email WooCommerce email. |
| 42 | * @return string |
| 43 | */ |
| 44 | public function get_woo_content( \WC_Email $wc_email ): string { |
| 45 | $woo_content = $this->capture_woo_content( $wc_email ); |
| 46 | $woo_content_with_css = $this->inline_css( $woo_content ); |
| 47 | return $this->get_html_body_content( $woo_content_with_css ); |
| 48 | } |
| 49 | |
| 50 | /** |
| 51 | * Filter CSS for the email. |
| 52 | * The CSS from the email editor was already inlined. |
| 53 | * The method hooks to woocommerce_email_styles and removes CSS rules that we don't want to apply to the email. |
| 54 | * |
| 55 | * Typography properties (font-size, font-weight, line-height, letter-spacing) are stripped |
| 56 | * because the email editor theme controls all typography via theme.json. Leaving these in |
| 57 | * the WooCommerce CSS would override the editor's heading sizes and weights. |
| 58 | * |
| 59 | * @since 10.8.0 |
| 60 | * @param string $css CSS. |
| 61 | * @return string |
| 62 | */ |
| 63 | public function prepare_css( string $css ): string { |
| 64 | remove_filter( 'woocommerce_email_styles', array( $this, 'prepare_css' ) ); |
| 65 | // Remove typography declarations from WooCommerce CSS. |
| 66 | // The email editor theme.json controls all typography; WC CSS would override it. |
| 67 | return (string) preg_replace( |
| 68 | array( |
| 69 | '/color\s*:\s*[^;]+;/', |
| 70 | '/font-family\s*:\s*[^;]+;/', |
| 71 | '/font-size\s*:\s*[^;]+;/', |
| 72 | '/font-weight\s*:\s*[^;]+;/', |
| 73 | '/line-height\s*:\s*[^;]+;/', |
| 74 | '/letter-spacing\s*:\s*[^;]+;/', |
| 75 | ), |
| 76 | '', |
| 77 | $css |
| 78 | ); |
| 79 | } |
| 80 | |
| 81 | /** |
| 82 | * Get the content of the body tag from the HTML. |
| 83 | * |
| 84 | * @param string $html HTML. |
| 85 | * @return string |
| 86 | */ |
| 87 | private function get_html_body_content( string $html ): string { |
| 88 | // Extract content between <body> and </body> tags using regex. |
| 89 | if ( preg_match( '/<body[^>]*>(.*?)<\/body>/is', $html, $matches ) ) { |
| 90 | return $matches[1]; |
| 91 | } |
| 92 | return $html; |
| 93 | } |
| 94 | |
| 95 | /** |
| 96 | * Inline the CSS from the email theme and user email settings. |
| 97 | * |
| 98 | * @param string $woo_content WooCommerce content. |
| 99 | * @return string |
| 100 | */ |
| 101 | private function inline_css( string $woo_content ): string { |
| 102 | if ( empty( $woo_content ) ) { |
| 103 | return ''; |
| 104 | } |
| 105 | $css = $this->theme_controller->get_stylesheet_for_rendering(); |
| 106 | $css .= $this->get_woo_content_styles(); |
| 107 | return $this->css_inliner->from_html( $woo_content )->inline_css( $css )->render(); |
| 108 | } |
| 109 | |
| 110 | /** |
| 111 | * Get CSS styles specific to WooCommerce email content. |
| 112 | * |
| 113 | * These styles target WooCommerce-specific HTML classes in the order details, |
| 114 | * totals, and other email content areas. They are needed because the WooCommerce |
| 115 | * email CSS selectors (prefixed with #body_content) do not match in the block |
| 116 | * email editor template structure. |
| 117 | * |
| 118 | * @since 10.8.0 |
| 119 | * @return string CSS styles. |
| 120 | */ |
| 121 | private function get_woo_content_styles(): string { |
| 122 | return ' |
| 123 | .email-order-details td, |
| 124 | .email-order-details th { |
| 125 | padding: 8px 12px; |
| 126 | } |
| 127 | .email-order-details td:first-child, |
| 128 | .email-order-details th:first-child { |
| 129 | padding-left: 0; |
| 130 | } |
| 131 | .email-order-details td:last-child, |
| 132 | .email-order-details th:last-child { |
| 133 | padding-right: 0; |
| 134 | } |
| 135 | .order-item-data td { |
| 136 | border: 0; |
| 137 | padding: 0; |
| 138 | vertical-align: top; |
| 139 | } |
| 140 | .order-item-data img { |
| 141 | border-radius: 4px; |
| 142 | } |
| 143 | .order-totals th, |
| 144 | .order-totals td { |
| 145 | font-weight: 400; |
| 146 | padding-bottom: 5px; |
| 147 | padding-top: 5px; |
| 148 | } |
| 149 | .order-totals-total th { |
| 150 | font-weight: 700; |
| 151 | } |
| 152 | .order-totals-total td { |
| 153 | font-weight: 700; |
| 154 | font-size: 20px; |
| 155 | } |
| 156 | h2.email-order-detail-heading { |
| 157 | font-size: 20px; |
| 158 | font-weight: 700; |
| 159 | line-height: 1.6; |
| 160 | } |
| 161 | h2.email-order-detail-heading span { |
| 162 | font-size: 14px; |
| 163 | font-weight: 400; |
| 164 | color: #757575; |
| 165 | } |
| 166 | .email-order-item-meta { |
| 167 | font-size: 14px; |
| 168 | line-height: 1.4; |
| 169 | } |
| 170 | '; |
| 171 | } |
| 172 | |
| 173 | /** |
| 174 | * Capture the WooCommerce content excluding headers and footers. |
| 175 | * |
| 176 | * @param \WC_Email $wc_email WooCommerce email. |
| 177 | * @return string |
| 178 | */ |
| 179 | private function capture_woo_content( \WC_Email $wc_email ): string { |
| 180 | return $wc_email->get_block_editor_email_template_content(); |
| 181 | } |
| 182 | } |
| 183 |