fix: resolve container width issues, spa redirects, and appearance settings overwrite. feat: enhance order/sub details and newsletter layout

This commit is contained in:
Dwindi Ramadhana
2026-02-05 00:09:40 +07:00
parent a0b5f8496d
commit 5f08c18ec7
77 changed files with 7027 additions and 4546 deletions

View File

@@ -89,7 +89,7 @@ class EmailRenderer
* @param string $recipient_type
* @return array|null
*/
private function get_template_settings($event_id, $recipient_type)
public function get_template_settings($event_id, $recipient_type)
{
// Get saved template (with recipient_type for proper default template lookup)
$template = TemplateProvider::get_template($event_id, 'email', $recipient_type);
@@ -187,7 +187,7 @@ class EmailRenderer
'site_name' => get_bloginfo('name'),
'site_title' => get_bloginfo('name'),
'store_name' => get_bloginfo('name'),
'store_url' => home_url(),
'site_url' => home_url(),
'shop_url' => get_permalink(wc_get_page_id('shop')),
'my_account_url' => get_permalink(wc_get_page_id('myaccount')),
'support_email' => get_option('admin_email'),
@@ -381,7 +381,7 @@ class EmailRenderer
* @param string $content
* @return string
*/
private function parse_cards($content)
public function parse_cards($content)
{
// Use a single unified regex to match BOTH syntaxes in document order
// This ensures cards are rendered in the order they appear
@@ -473,8 +473,31 @@ class EmailRenderer
$hero_text_color = '#ffffff'; // Always white on gradient
// Parse button shortcodes with FULL INLINE STYLES for Gmail compatibility
// Helper function to escape URL while preserving variable placeholders like {unsubscribe_url}
$escape_url_preserving_variables = function ($url) {
// If URL contains variable placeholder, don't escape (will be replaced later)
if (preg_match('/\{[a-z_]+\}/', $url)) {
// Just return the URL as-is - it will be replaced with a real URL later
return $url;
}
return esc_url($url);
};
// Helper function to generate button HTML
$generateButtonHtml = function ($url, $style, $text) use ($primary_color, $secondary_color, $button_text_color) {
$generateButtonHtml = function ($url, $style, $text) use ($primary_color, $secondary_color, $button_text_color, $escape_url_preserving_variables) {
$escaped_url = $escape_url_preserving_variables($url);
if ($style === 'link') {
// Plain link - just a simple <a> tag styled like regular text link (inline, no wrapper)
return sprintf(
'<a href="%s" style="color: %s; text-decoration: underline; font-family: \'Inter\', Arial, sans-serif;">%s</a>',
$escaped_url,
esc_attr($primary_color),
esc_html($text)
);
}
// Styled buttons (solid/outline) get table wrapper for email client compatibility
if ($style === 'outline') {
// Outline button - transparent background with border
$button_style = sprintf(
@@ -494,7 +517,7 @@ class EmailRenderer
// Use table-based button for better email client compatibility
return sprintf(
'<table role="presentation" border="0" cellpadding="0" cellspacing="0" style="margin: 16px auto;"><tr><td align="center"><a href="%s" style="%s">%s</a></td></tr></table>',
esc_url($url),
$escaped_url,
$button_style,
esc_html($text)
);
@@ -542,9 +565,25 @@ class EmailRenderer
$content_style .= sprintf(' color: %s;', esc_attr($hero_text_color));
// Add inline color to all headings and paragraphs for email client compatibility
$content = preg_replace(
'/<(h[1-6]|p)([^>]*)>/',
'<$1$2 style="color: ' . esc_attr($hero_text_color) . ';">',
// Preserve existing style attributes (like text-align) by appending to them
$content = preg_replace_callback(
'/<(h[1-6]|p)([^>]*?)(\s+style=["\']([^"\']*)["\'])?([^>]*)>/',
function ($matches) use ($hero_text_color) {
$tag = $matches[1];
$before_style = $matches[2];
$existing_style = isset($matches[4]) ? $matches[4] : '';
$after_style = $matches[5];
$color_style = 'color: ' . esc_attr($hero_text_color) . ';';
if ($existing_style) {
// Append to existing style
$new_style = rtrim($existing_style, ';') . '; ' . $color_style;
return '<' . $tag . $before_style . ' style="' . $new_style . '"' . $after_style . '>';
} else {
// Add new style attribute
return '<' . $tag . $before_style . ' style="' . $color_style . '"' . $after_style . '>';
}
},
$content
);
}
@@ -560,6 +599,11 @@ class EmailRenderer
elseif ($type === 'warning') {
$style .= ' background-color: #fff8e1;';
}
// Basic card - plain text, no card styling (for footers/muted content)
elseif ($type === 'basic') {
$style = 'width: 100%; background-color: transparent;'; // No background
$content_style = 'padding: 0;'; // No padding
}
}
// Add background image
@@ -616,7 +660,7 @@ class EmailRenderer
*
* @return string
*/
private function get_design_template()
public function get_design_template()
{
// Use single base template (theme-agnostic)
$template_path = WOONOOW_PATH . 'templates/emails/base.html';
@@ -641,7 +685,7 @@ class EmailRenderer
* @param array $variables All variables
* @return string
*/
private function render_html($template_path, $content, $subject, $variables)
public function render_html($template_path, $content, $subject, $variables)
{
if (!file_exists($template_path)) {
// Fallback to plain HTML
@@ -654,6 +698,10 @@ class EmailRenderer
// Get email customization settings
$email_settings = get_option('woonoow_email_settings', []);
// Ensure required variables have defaults
$variables['site_url'] = $variables['site_url'] ?? home_url();
$variables['store_name'] = $variables['store_name'] ?? get_bloginfo('name');
// Email body background
$body_bg = '#f8f8f8';
@@ -668,7 +716,7 @@ class EmailRenderer
if (!empty($logo_url)) {
$header = sprintf(
'<a href="%s"><img src="%s" alt="%s" style="max-width: 200px; max-height: 60px;"></a>',
esc_url($variables['store_url']),
esc_url($variables['site_url']),
esc_url($logo_url),
esc_attr($variables['store_name'])
);
@@ -677,7 +725,7 @@ class EmailRenderer
$header_text = !empty($email_settings['header_text']) ? $email_settings['header_text'] : $variables['store_name'];
$header = sprintf(
'<a href="%s" style="font-size: 24px; font-weight: 700; color: #333; text-decoration: none;">%s</a>',
esc_url($variables['store_url']),
esc_url($variables['site_url']),
esc_html($header_text)
);
}
@@ -724,7 +772,7 @@ class EmailRenderer
$html = str_replace('{{email_content}}', $content, $html);
$html = str_replace('{{email_footer}}', $footer, $html);
$html = str_replace('{{store_name}}', esc_html($variables['store_name']), $html);
$html = str_replace('{{store_url}}', esc_url($variables['store_url']), $html);
$html = str_replace('{{site_url}}', esc_url($variables['site_url']), $html);
$html = str_replace('{{current_year}}', date('Y'), $html);
// Replace all other variables