PluginProbe ʕ •ᴥ•ʔ
MailPoet – Newsletters, Email Marketing, and Automation / 5.34.3
MailPoet – Newsletters, Email Marketing, and Automation v5.34.3
5.36.1 5.36.0 5.35.1 5.35.0 5.34.3 5.34.2 5.34.1 5.34.0 5.33.1 5.33.0 5.32.0 5.31.0 5.30.0 5.29.0 5.28.1 5.28.0 5.27.0 5.26.0 5.26.1 5.25.0 5.24.0 4.43.0 4.43.1 4.44.0 4.44.1 4.45.0 4.46.0 4.47.0 4.48.0 4.48.1 4.48.2 4.49.0 4.49.1 4.5.0 4.5.1 4.5.2 4.50.0 4.50.1 4.51.0 4.51.1 4.51.2 4.52.0 4.53.0 4.54.0 4.55.0 4.56.0 4.57.0 4.58.0 4.58.1 4.58.2 4.6.0 4.6.1 4.6.2 4.7.0 4.7.1 4.8.0 4.8.1 4.9.0 5.0.0 5.0.1 5.0.2 5.1.0 5.1.1 5.10.0 5.10.1 5.11.0 5.12.0 5.12.1 5.12.10 5.12.11 5.12.12 5.12.13 5.12.2 5.12.3 5.12.4 5.12.5 5.12.6 5.12.7 5.12.8 5.12.9 5.13.0 5.13.1 5.13.2 5.14.0 5.14.1 5.14.2 5.14.3 5.15.0 5.15.1 5.16.0 5.16.1 5.16.2 5.16.3 5.16.4 5.17.0 5.17.1 5.17.2 5.17.3 5.17.4 5.17.5 5.17.6 5.18.0 5.19.0 5.2.0 5.2.1 5.2.2 5.2.3 5.20.0 5.21.0 5.21.1 5.21.2 5.21.3 5.22.0 5.22.1 5.22.2 5.22.3 5.22.4 5.23.0 5.23.1 5.23.2 5.3.0 5.3.1 5.3.2 5.3.3 5.3.4 5.3.5 5.3.6 5.3.7 5.4.0 5.4.1 5.4.2 5.5.0 5.5.1 5.5.2 5.6.0 5.6.1 5.6.2 5.6.3 5.6.4 5.7.0 5.7.1 5.8.0 5.8.1 5.9.0 3.0.0-beta.15 3.7.1 3.0.0-beta.16 3.7.2 3.0.0-beta.17 3.7.3 3.0.0-beta.18 3.7.4 3.0.0-beta.19 3.7.5 3.0.0-beta.2 3.7.6 3.0.0-beta.20 3.7.8 3.0.0-beta.21 3.70.0 3.0.0-beta.22 3.71.0 3.0.0-beta.23 3.71.1 3.0.0-beta.23.1 3.71.2 3.0.0-beta.23.2 3.71.3 3.0.0-beta.24 3.72.0 3.0.0-beta.25 3.73.0 3.0.0-beta.26 3.73.1 3.0.0-beta.27 3.73.2 3.0.0-beta.28 3.74.0 3.0.0-beta.29 3.74.1 3.0.0-beta.3 3.74.2 3.0.0-beta.30 3.74.3 3.0.0-beta.31 3.75.0 3.0.0-beta.32 3.75.1 3.0.0-beta.33 3.76.0 3.0.0-beta.33.1 3.77.0 3.0.0-beta.34.0.0 3.77.1 3.0.0-beta.36.0.0 3.78.0 3.0.0-beta.36.0.1 3.79.0 3.0.0-beta.36.2.0 3.8 3.0.0-beta.36.3.0 3.8.1 3.0.0-beta.36.3.1 3.8.2 3.0.0-beta.37.0.0 3.8.3 3.0.0-beta.4 3.8.4 3.0.0-beta.5 3.8.5 3.0.0-beta.6 3.8.6 3.0.0-beta.7 3.80.0 3.0.0-beta.7.1 3.81.0 3.0.0-beta.8 3.82.0 3.0.0-beta.9 3.83.0 3.0.0-rc.1.0.0 3.84.0 3.0.0-rc.1.0.1 3.84.1 3.0.0-rc.1.0.2 3.85.0 3.0.0-rc.1.0.3 3.85.1 3.0.0-rc.1.0.4 3.86.0 3.0.0-rc.2.0.0 3.87.0 3.0.0-rc.2.0.1 3.87.1 3.0.0-rc.2.0.2 3.87.2 3.0.0-rc.2.0.3 3.88.0 3.0.1 3.88.1 3.0.2 3.88.2 3.0.3 3.89.0 3.0.4 3.89.1 3.0.5 3.89.2 3.0.6 3.89.3 3.0.7 3.89.4 3.0.8 3.9.0 3.0.9 3.9.1 3.1.0 3.90.0 3.10 3.90.1 3.10.1 3.90.2 3.100.0 3.91.0 3.100.1 3.91.1 3.100.2 3.92.0 3.101.0 3.92.1 3.101.1 3.93.0 3.102.0 3.93.1 3.102.1 3.94.0 3.103.0 3.95.0 3.103.1 3.95.1 3.11.0 3.96.0 3.11.1 3.96.1 3.11.2 3.97.0 3.11.3 3.98.0 3.11.4 3.98.1 3.11.5 3.99.0 3.12.0 3.99.1 3.12.1 4.0.0 3.13.0 4.0.1 3.14.0 4.1.0 3.14.1 4.1.1 3.15.0 4.10.0 3.16.0 4.11.0 3.16.1 4.11.1 3.16.2 4.12.0 3.16.3 4.12.1 3.17.0 4.12.2 3.17.1 4.13.0 3.17.2 4.14.0 3.18.0 4.15.0 3.18.1 4.16.0 3.18.2 4.17.0 3.19.0 4.17.1 3.19.1 4.18.0 3.19.2 4.18.1 3.19.3 4.19.0 3.2.0 4.2.0 3.2.1 4.20.0 3.2.2 4.20.1 3.2.3 4.20.2 3.2.4 4.21.0 3.2.5 4.22.0 3.20.0 4.22.1 3.21.0 4.22.2 3.21.1 4.23.0 3.22.0 4.24.0 3.23.0 4.25.0 3.23.1 4.26.0 3.23.2 4.26.1 3.24.0 4.27.0 3.25.0 4.28.0 3.25.1 4.29.0 3.26.0 4.3.0 3.26.1 4.3.1 3.27.0 4.30.0 3.28.0 4.31.0 3.29.0 4.31.1 3.3.0 4.32.0 3.3.1 4.33.0 3.3.2 4.34.0 3.3.3 4.35.0 3.3.4 4.35.1 3.3.5 4.36.0 3.3.6 4.37.0 3.30.0 4.38.0 3.31.0 4.39.0 3.31.1 4.4.0 3.32.0 4.40.0 3.32.1 4.41.0 3.32.2 4.41.1 3.33.0 4.41.2 3.34.0 4.41.3 3.34.1 4.42.0 3.34.2 4.42.1 3.34.3 3.34.4 3.35.0 3.35.1 3.35.3 3.35.4 3.36.0 3.37.0 3.37.1 3.37.2 3.37.3 3.38.0 3.38.1 3.39.0 3.39.1 3.39.2 3.4.0 3.4.1 3.4.2 3.4.3 3.4.4 3.40.0 3.40.1 3.41.0 3.41.1 3.41.2 3.42.0 3.42.1 3.42.2 3.42.3 3.43.0 3.43.1 3.44.0 3.45.0 3.45.1 3.46.0 3.46.1 3.46.10 3.46.11 3.46.12 3.46.13 3.46.14 3.46.2 3.46.3 3.46.4 3.46.5 3.46.6 3.46.7 3.46.8 3.46.9 3.47.0 3.47.1 3.47.10 3.47.11 3.47.2 3.47.3 3.47.5 3.47.6 3.47.7 3.47.9 3.48.0 3.48.1 3.49.0 3.49.1 3.5.0 3.5.1 3.50.0 3.51.0 3.51.1 3.51.2 3.52.0 3.53.0 3.54.0 3.54.1 3.54.2 3.54.3 3.55.0 3.55.1 3.56.0 3.56.1 3.56.2 3.57.0 3.57.1 3.58.0 3.59.0 3.59.1 3.59.2 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.6.5 3.6.6 3.6.7 3.60.0 3.60.1 3.60.10 3.60.11 3.60.12 3.60.2 3.60.3 3.60.4 3.60.6 3.60.7 3.60.8 3.60.9 3.61.0 3.62.0 3.62.1 3.63.0 3.64.0 3.64.1 3.64.2 3.64.3 3.65.0 trunk 3.65.1 3.0.0 3.66.0 3.0.0-beta.1 3.67.0 3.0.0-beta.10 3.67.1 3.0.0-beta.11 3.68.0 3.0.0-beta.12 3.69.0 3.0.0-beta.13 3.69.1 3.0.0-beta.14 3.7.0
mailpoet / vendor / woocommerce / email-editor / src / Engine / Renderer / ContentRenderer / class-content-renderer.php
mailpoet / vendor / woocommerce / email-editor / src / Engine / Renderer / ContentRenderer Last commit date
Layout 3 months ago Postprocessors 11 months ago Preprocessors 3 months ago class-block-renderer.php 1 year ago class-blocks-parser.php 1 year ago class-content-renderer.php 3 months ago class-preset-variable-resolver.php 4 months ago class-process-manager.php 3 months ago class-rendering-context.php 3 months ago content.css 1 year ago index.php 1 year ago
class-content-renderer.php
336 lines
1 <?php
2 declare(strict_types = 1);
3 namespace Automattic\WooCommerce\EmailEditor\Engine\Renderer\ContentRenderer;
4 if (!defined('ABSPATH')) exit;
5 use Automattic\WooCommerce\EmailEditor\Engine\Logger\Email_Editor_Logger;
6 use Automattic\WooCommerce\EmailEditor\Engine\Renderer\Css_Inliner;
7 use Automattic\WooCommerce\EmailEditor\Engine\Theme_Controller;
8 use Automattic\WooCommerce\EmailEditor\Integrations\Core\Renderer\Blocks\Fallback;
9 use Automattic\WooCommerce\EmailEditor\Integrations\Core\Renderer\Blocks\Post_Content;
10 use Automattic\WooCommerce\EmailEditor\Integrations\Utils\Table_Wrapper_Helper;
11 use WP_Block_Template;
12 use WP_Block_Type_Registry;
13 use WP_Post;
14 use WP_Style_Engine;
15 class Content_Renderer {
16 private Process_Manager $process_manager;
17 private Theme_Controller $theme_controller;
18 const CONTENT_STYLES_FILE = 'content.css';
19 private WP_Block_Type_Registry $block_type_registry;
20 private $backup_template_content;
21 private $backup_template_id;
22 private $backup_post;
23 private $backup_query;
24 private Fallback $fallback_renderer;
25 private Email_Editor_Logger $logger;
26 private $backup_post_content_callback;
27 private ?string $post_content_width = null;
28 private array $container_padding = array();
29 private Css_Inliner $css_inliner;
30 private ?Rendering_Context $rendering_context = null;
31 public function __construct(
32 Process_Manager $preprocess_manager,
33 Css_Inliner $css_inliner,
34 Theme_Controller $theme_controller,
35 Email_Editor_Logger $logger
36 ) {
37 $this->process_manager = $preprocess_manager;
38 $this->css_inliner = $css_inliner;
39 $this->theme_controller = $theme_controller;
40 $this->logger = $logger;
41 $this->block_type_registry = WP_Block_Type_Registry::get_instance();
42 $this->fallback_renderer = new Fallback();
43 }
44 private function initialize() {
45 add_filter( 'render_block', array( $this, 'render_block' ), 10, 2 );
46 add_filter( 'block_parser_class', array( $this, 'block_parser' ) );
47 add_filter( 'woocommerce_email_blocks_renderer_parsed_blocks', array( $this, 'preprocess_parsed_blocks' ) );
48 // Swap core/post-content render callback for email rendering.
49 // This prevents issues with WordPress's static $seen_ids array when rendering
50 // multiple emails in a single request (e.g., MailPoet batch processing).
51 $post_content_type = $this->block_type_registry->get_registered( 'core/post-content' );
52 if ( $post_content_type ) {
53 // Save the original callback (may be null or WordPress's default).
54 $this->backup_post_content_callback = $post_content_type->render_callback;
55 // Replace with our stateless renderer.
56 $post_content_renderer = new Post_Content();
57 $post_content_type->render_callback = array( $post_content_renderer, 'render_stateless' );
58 }
59 }
60 public function set_rendering_context( Rendering_Context $rendering_context ): void {
61 $this->rendering_context = $rendering_context;
62 }
63 public function get_current_rendering_context(): ?Rendering_Context {
64 return $this->rendering_context;
65 }
66 public function restore_rendering_context( ?Rendering_Context $rendering_context ): void {
67 $this->rendering_context = $rendering_context;
68 }
69 public function render( WP_Post $post, WP_Block_Template $template ): string {
70 $result = $this->render_without_css_inline( $post, $template );
71 $styles = '<style>' . $result['styles'] . '</style>';
72 $html = $this->css_inliner->from_html( $styles . $result['html'] )->inline_css()->render();
73 return $this->process_manager->postprocess( $html );
74 }
75 public function render_without_css_inline( WP_Post $post, WP_Block_Template $template ): array {
76 if ( null === $this->rendering_context ) {
77 $this->rendering_context = $this->create_rendering_context( null, $post, $template );
78 }
79 $this->set_template_globals( $post, $template );
80 $this->initialize();
81 try {
82 do_action( 'woocommerce_email_editor_render_start' );
83 $rendered_html = get_the_block_template_html();
84 } finally {
85 $this->reset();
86 }
87 return array(
88 'html' => $rendered_html,
89 'styles' => $this->collect_styles( $post, $template ),
90 );
91 }
92 public function block_parser() {
93 return 'Automattic\WooCommerce\EmailEditor\Engine\Renderer\ContentRenderer\Blocks_Parser';
94 }
95 public function preprocess_parsed_blocks( array $parsed_blocks ): array {
96 $styles = $this->theme_controller->get_styles();
97 $layout = $this->theme_controller->get_layout_settings();
98 // Pass the CSS variables map so preprocessors can resolve preset
99 // references (e.g. var:preset|spacing|20) in block attributes.
100 $styles['__variables_map'] = $this->theme_controller->get_variables_values_map();
101 // Second pass (user blocks inside post-content): if root padding was
102 // applied to a container above post-content in the first pass (indicated
103 // by post_content_width < contentSize), remove root padding from styles
104 // to prevent double application. If the template delegates root padding
105 // (post_content_width == contentSize), keep it for user blocks.
106 if ( null !== $this->post_content_width ) {
107 $post_content_num = (float) str_replace( 'px', '', $this->post_content_width );
108 $content_size_num = (float) str_replace( 'px', '', $layout['contentSize'] );
109 // Use epsilon tolerance for floating-point comparison since width
110 // calculations involve round() and division that may produce imprecision.
111 if ( $post_content_num < $content_size_num - 0.01 ) {
112 unset( $styles['spacing']['padding']['left'], $styles['spacing']['padding']['right'] );
113 }
114 // Pass container padding from the first pass so the
115 // Spacing_Preprocessor can distribute it to user blocks.
116 if ( ! empty( $this->container_padding ) ) {
117 $styles['__container_padding'] = $this->container_padding;
118 }
119 }
120 $result = $this->process_manager->preprocess( $parsed_blocks, $layout, $styles, $this->get_rendering_context() );
121 // After the first pass: find the post-content block's width and container padding.
122 if ( null === $this->post_content_width ) {
123 $this->post_content_width = $this->find_post_content_width( $result );
124 $this->container_padding = $this->find_container_padding( $result );
125 }
126 return $result;
127 }
128 private function find_post_content_width( array $blocks, ?array $post_content_block_names = null ): ?string {
129 if ( null === $post_content_block_names ) {
130 $post_content_block_names = (array) apply_filters(
131 'woocommerce_email_editor_post_content_block_names',
132 array( 'core/post-content' )
133 );
134 }
135 foreach ( $blocks as $block ) {
136 $block_name = $block['blockName'] ?? '';
137 if ( in_array( $block_name, $post_content_block_names, true ) ) {
138 return $block['email_attrs']['width'] ?? null;
139 }
140 if ( ! empty( $block['innerBlocks'] ) ) {
141 $found = $this->find_post_content_width( $block['innerBlocks'], $post_content_block_names );
142 if ( null !== $found ) {
143 return $found;
144 }
145 }
146 }
147 return null;
148 }
149 private function find_container_padding( array $blocks ): array {
150 $variables_map = $this->theme_controller->get_variables_values_map();
151 foreach ( $blocks as $block ) {
152 $email_attrs = $block['email_attrs'] ?? array();
153 if ( ! empty( $email_attrs['suppress-horizontal-padding'] ) ) {
154 $padding = $block['attrs']['style']['spacing']['padding'] ?? array();
155 $result = array();
156 if ( isset( $padding['left'] ) && is_string( $padding['left'] ) ) {
157 $result['left'] = Preset_Variable_Resolver::resolve( $padding['left'], $variables_map );
158 }
159 if ( isset( $padding['right'] ) && is_string( $padding['right'] ) ) {
160 $result['right'] = Preset_Variable_Resolver::resolve( $padding['right'], $variables_map );
161 }
162 if ( ! empty( $result ) ) {
163 return $result;
164 }
165 }
166 if ( ! empty( $block['innerBlocks'] ) ) {
167 $found = $this->find_container_padding( $block['innerBlocks'] );
168 if ( ! empty( $found ) ) {
169 return $found;
170 }
171 }
172 }
173 return array();
174 }
175 public function render_block( string $block_content, array $parsed_block ): string {
176 $context = $this->get_rendering_context();
177 $block_type = $this->block_type_registry->get_registered( $parsed_block['blockName'] );
178 $result = null;
179 try {
180 if ( $block_type && isset( $block_type->render_email_callback ) && is_callable( $block_type->render_email_callback ) ) {
181 $result = call_user_func( $block_type->render_email_callback, $block_content, $parsed_block, $context );
182 }
183 } catch ( \Exception $error ) {
184 $this->logger->error(
185 'Error thrown while rendering block.',
186 array(
187 'exception' => $error,
188 'block_name' => $parsed_block['blockName'],
189 'parsed_block' => $parsed_block,
190 'message' => $error->getMessage(),
191 )
192 );
193 // Returning the original content.
194 return $block_content;
195 }
196 if ( null === $result ) {
197 $result = $this->fallback_renderer->render( $block_content, $parsed_block, $context );
198 }
199 return $this->add_root_horizontal_padding( $result, $parsed_block['email_attrs'] ?? array() );
200 }
201 private function add_root_horizontal_padding( string $content, array $email_attrs ): string {
202 $padding_left = $this->sum_padding_values(
203 $email_attrs['root-padding-left'] ?? null,
204 $email_attrs['container-padding-left'] ?? null
205 );
206 $padding_right = $this->sum_padding_values(
207 $email_attrs['root-padding-right'] ?? null,
208 $email_attrs['container-padding-right'] ?? null
209 );
210 $css_attrs = array();
211 if ( $padding_left > 0 ) {
212 $css_attrs['padding-left'] = $padding_left . 'px';
213 }
214 if ( $padding_right > 0 ) {
215 $css_attrs['padding-right'] = $padding_right . 'px';
216 }
217 if ( empty( $css_attrs ) ) {
218 return $content;
219 }
220 $padding_style = WP_Style_Engine::compile_css( $css_attrs, '' );
221 if ( empty( $padding_style ) ) {
222 return $content;
223 }
224 $table_attrs = array(
225 'align' => $this->get_rendering_context()->get_default_text_align(),
226 'width' => '100%',
227 );
228 $cell_attrs = array(
229 'style' => $padding_style,
230 );
231 $div_content = sprintf(
232 '<div class="email-root-padding" style="%1$s">%2$s</div>',
233 esc_attr( $padding_style ),
234 $content
235 );
236 return Table_Wrapper_Helper::render_outlook_table_wrapper( $div_content, $table_attrs, $cell_attrs );
237 }
238 private function sum_padding_values( ?string $value1, ?string $value2 ): float {
239 $sum = 0.0;
240 if ( null !== $value1 ) {
241 $sum += (float) str_replace( 'px', '', $value1 );
242 }
243 if ( null !== $value2 ) {
244 $sum += (float) str_replace( 'px', '', $value2 );
245 }
246 return $sum;
247 }
248 private function set_template_globals( WP_Post $email_post, WP_Block_Template $template ) {
249 global $_wp_current_template_content, $_wp_current_template_id, $wp_query, $post;
250 // Backup current values of globals.
251 // Because overriding the globals can affect rendering of the page itself, we need to backup the current values.
252 $this->backup_template_content = $_wp_current_template_content;
253 $this->backup_template_id = $_wp_current_template_id;
254 $this->backup_query = $wp_query;
255 $this->backup_post = $post;
256 $_wp_current_template_id = $template->id;
257 $_wp_current_template_content = $template->content;
258 $wp_query = new \WP_Query( array( 'p' => $email_post->ID ) ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- We need to set the query for correct rendering the blocks.
259 $post = $email_post; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- We need to set the post for correct rendering the blocks.
260 }
261 private function reset(): void {
262 remove_filter( 'render_block', array( $this, 'render_block' ) );
263 remove_filter( 'block_parser_class', array( $this, 'block_parser' ) );
264 remove_filter( 'woocommerce_email_blocks_renderer_parsed_blocks', array( $this, 'preprocess_parsed_blocks' ) );
265 $this->post_content_width = null;
266 $this->container_padding = array();
267 $this->rendering_context = null;
268 // Restore the original core/post-content render callback.
269 // Note: We always restore it, even if it was null originally.
270 $post_content_type = $this->block_type_registry->get_registered( 'core/post-content' );
271 if ( $post_content_type ) {
272 // @phpstan-ignore-next-line -- WordPress core allows null for render_callback despite type definition.
273 $post_content_type->render_callback = $this->backup_post_content_callback;
274 }
275 // Restore globals to their original values.
276 global $_wp_current_template_content, $_wp_current_template_id, $wp_query, $post;
277 $_wp_current_template_content = $this->backup_template_content;
278 $_wp_current_template_id = $this->backup_template_id;
279 $wp_query = $this->backup_query; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Restoring of the query.
280 $post = $this->backup_post; // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- Restoring of the post.
281 }
282 private function get_rendering_context(): Rendering_Context {
283 if ( null === $this->rendering_context ) {
284 $this->rendering_context = $this->create_rendering_context();
285 }
286 return $this->rendering_context;
287 }
288 public function create_rendering_context( ?string $language = null, ?WP_Post $post = null, ?WP_Block_Template $template = null ): Rendering_Context {
289 $email_context = apply_filters( 'woocommerce_email_editor_rendering_email_context', array(), $post, $template );
290 if ( ! is_array( $email_context ) ) {
291 $email_context = array();
292 }
293 return new Rendering_Context( $this->theme_controller->get_theme(), $email_context, $language );
294 }
295 private function collect_styles( WP_Post $post, $template = null ): string {
296 $styles = (string) file_get_contents( __DIR__ . '/' . self::CONTENT_STYLES_FILE );
297 $styles .= (string) file_get_contents( __DIR__ . '/../../content-shared.css' );
298 // Apply default contentWidth to constrained blocks.
299 $layout = $this->theme_controller->get_layout_settings();
300 $styles .= sprintf(
301 '
302 .is-layout-constrained > *:not(.alignleft):not(.alignright):not(.alignfull) {
303 max-width: %1$s;
304 margin-left: auto !important;
305 margin-right: auto !important;
306 }
307 .is-layout-constrained > .alignwide {
308 max-width: %2$s;
309 margin-left: auto !important;
310 margin-right: auto !important;
311 }
312 ',
313 $layout['contentSize'],
314 $layout['wideSize'] ?? $layout['contentSize']
315 );
316 // Get styles from theme.
317 $styles .= $this->theme_controller->get_stylesheet_for_rendering( $post, $template );
318 $block_support_styles = $this->theme_controller->get_stylesheet_from_context( 'block-supports', array() );
319 // Get styles from block-supports stylesheet. This includes rules such as layout (contentWidth) that some blocks use.
320 // @see https://github.com/WordPress/WordPress/blob/3c5da9c74344aaf5bf8097f2e2c6a1a781600e03/wp-includes/script-loader.php#L3134
321 // @internal :where is not supported by emogrifier, so we need to replace it with *.
322 $block_support_styles = str_replace(
323 ':where(:not(.alignleft):not(.alignright):not(.alignfull))',
324 '*:not(.alignleft):not(.alignright):not(.alignfull)',
325 $block_support_styles
326 );
327 $block_support_styles = preg_replace(
328 '/group-is-layout-(\d+) >/',
329 'group-is-layout-$1 > tbody tr td >',
330 $block_support_styles
331 );
332 $styles .= $block_support_styles;
333 return wp_strip_all_tags( (string) apply_filters( 'woocommerce_email_content_renderer_styles', $styles, $post ) );
334 }
335 }
336