diff --git a/includes/Core/Notifications/EmailRenderer.php b/includes/Core/Notifications/EmailRenderer.php index 95c0423..3509a25 100644 --- a/includes/Core/Notifications/EmailRenderer.php +++ b/includes/Core/Notifications/EmailRenderer.php @@ -57,11 +57,14 @@ class EmailRenderer { $subject = $this->replace_variables($template_settings['subject'], $variables); $content = $this->replace_variables($template_settings['body'], $variables); - // Get HTML template design - $design_template = $this->get_design_template($template_settings['design'] ?? 'modern'); + // Parse cards in content + $content = $this->parse_cards($content); + + // Get HTML template + $template_path = $this->get_design_template(); // Render final HTML - $html = $this->render_html($design_template, $content, $subject, $variables); + $html = $this->render_html($template_path, $content, $subject, $variables); return [ 'to' => $to, @@ -204,6 +207,111 @@ class EmailRenderer { return apply_filters('woonoow_email_variables', $variables, $event_id, $data); } + /** + * Parse [card] tags and convert to HTML + * + * @param string $content + * @return string + */ + private function parse_cards($content) { + // Match [card ...] ... [/card] patterns + preg_match_all('/\[card([^\]]*)\](.*?)\[\/card\]/s', $content, $matches, PREG_SET_ORDER); + + if (empty($matches)) { + // No cards found, wrap entire content in a single card + return $this->render_card($content, []); + } + + $html = ''; + foreach ($matches as $match) { + $attributes = $this->parse_card_attributes($match[1]); + $card_content = $match[2]; + + $html .= $this->render_card($card_content, $attributes); + $html .= $this->render_card_spacing(); + } + + // Remove last spacing + $html = preg_replace('/]*class="card-spacing"[^>]*>.*?<\/table>\s*$/s', '', $html); + + return $html; + } + + /** + * Parse card attributes from [card ...] tag + * + * @param string $attr_string + * @return array + */ + private function parse_card_attributes($attr_string) { + $attributes = [ + 'type' => 'default', + 'bg' => null, + ]; + + // Parse type="highlight" + if (preg_match('/type=["\']([^"\']+)["\']/', $attr_string, $match)) { + $attributes['type'] = $match[1]; + } + + // Parse bg="url" + if (preg_match('/bg=["\']([^"\']+)["\']/', $attr_string, $match)) { + $attributes['bg'] = $match[1]; + } + + return $attributes; + } + + /** + * Render a single card + * + * @param string $content + * @param array $attributes + * @return string + */ + private function render_card($content, $attributes) { + $type = $attributes['type'] ?? 'default'; + $bg = $attributes['bg'] ?? null; + + $class = 'card'; + $style = 'width: 100%; background-color: #ffffff; border-radius: 8px;'; + + // Add type class + if ($type !== 'default') { + $class .= ' card-' . esc_attr($type); + } + + // Add background image + if ($bg) { + $class .= ' card-bg'; + $style .= ' background-image: url(' . esc_url($bg) . ');'; + } + + return sprintf( + ' + + + + ', + $class, + $style, + $content + ); + } + + /** + * Render card spacing + * + * @return string + */ + private function render_card_spacing() { + return ' + +
 
'; + } + /** * Replace variables in text * @@ -222,18 +330,18 @@ class EmailRenderer { /** * Get design template path * - * @param string $design Template name (modern, classic, minimal) * @return string */ - private function get_design_template($design) { - $template_path = WOONOOW_PATH . 'templates/emails/' . $design . '.html'; + private function get_design_template() { + // Use single base template (theme-agnostic) + $template_path = WOONOOW_PATH . 'templates/emails/base.html'; // Allow filtering template path - $template_path = apply_filters('woonoow_email_template', $template_path, $design); + $template_path = apply_filters('woonoow_email_template', $template_path); - // Fallback to modern if template doesn't exist + // Fallback to base if custom template doesn't exist if (!file_exists($template_path)) { - $template_path = WOONOOW_PATH . 'templates/emails/modern.html'; + $template_path = WOONOOW_PATH . 'templates/emails/base.html'; } return $template_path; @@ -257,11 +365,69 @@ class EmailRenderer { // Load template $html = file_get_contents($template_path); + // Get email customization settings + $settings = get_option('woonoow_notification_settings', []); + $email_settings = $settings['email_appearance'] ?? []; + + // Email body background + $body_bg = $email_settings['body_bg'] ?? '#f8f8f8'; + + // Email header (logo or text) + $header_type = $email_settings['header_type'] ?? 'text'; + if ($header_type === 'logo' && !empty($email_settings['header_logo'])) { + $header = sprintf( + '%s', + esc_url($variables['store_url']), + esc_url($email_settings['header_logo']), + esc_attr($variables['store_name']) + ); + } else { + $header_text = $email_settings['header_text'] ?? $variables['store_name']; + $header = sprintf( + '%s', + esc_url($variables['store_url']), + esc_html($header_text) + ); + } + + // Email footer + $footer_text = $email_settings['footer_text'] ?? sprintf( + '© %s %s. All rights reserved.', + date('Y'), + $variables['store_name'] + ); + + // Social icons + $social_html = ''; + if (!empty($email_settings['social_links'])) { + $social_html = '
'; + foreach ($email_settings['social_links'] as $platform => $url) { + if (!empty($url)) { + $social_html .= sprintf( + '%s', + esc_url($url), + $this->get_social_icon_url($platform), + esc_attr(ucfirst($platform)) + ); + } + } + $social_html .= '
'; + } + + $footer = sprintf( + '

%s

%s', + nl2br(esc_html($footer_text)), + $social_html + ); + // Replace placeholders - $html = str_replace('{{email_heading}}', $subject, $html); + $html = str_replace('{{email_subject}}', esc_html($subject), $html); + $html = str_replace('{{email_body_bg}}', esc_attr($body_bg), $html); + $html = str_replace('{{email_header}}', $header, $html); $html = str_replace('{{email_content}}', $content, $html); - $html = str_replace('{{store_name}}', $variables['store_name'], $html); - $html = str_replace('{{store_url}}', $variables['store_url'], $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('{{current_year}}', date('Y'), $html); // Replace all other variables @@ -271,4 +437,22 @@ class EmailRenderer { return $html; } + + /** + * Get social icon URL + * + * @param string $platform + * @return string + */ + private function get_social_icon_url($platform) { + // You can host these icons or use a CDN + $icons = [ + 'facebook' => 'https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/facebook.svg', + 'instagram' => 'https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/instagram.svg', + 'twitter' => 'https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/twitter.svg', + 'linkedin' => 'https://cdn.jsdelivr.net/npm/simple-icons@v9/icons/linkedin.svg', + ]; + + return $icons[$platform] ?? ''; + } } diff --git a/includes/Core/Notifications/TemplateProvider.php b/includes/Core/Notifications/TemplateProvider.php index 9490463..65da7ee 100644 --- a/includes/Core/Notifications/TemplateProvider.php +++ b/includes/Core/Notifications/TemplateProvider.php @@ -143,7 +143,26 @@ class TemplateProvider { 'event_id' => 'order_placed', 'channel_id' => 'email', 'subject' => $wc_new_order['subject'] ?? __('New Order #{order_number}', 'woonoow'), - 'body' => __("Hi Admin,\n\nYou have received a new order.\n\nOrder Number: {order_number}\nOrder Total: {order_total}\nCustomer: {customer_name}\nEmail: {customer_email}\n\nView order: {order_url}", 'woonoow'), + 'body' => __('[card] +

New Order Received

+

Hi Admin,

+

You have received a new order from {customer_name}.

+
+

Order #{order_number}

+

Total: {order_total}

+
+[/card] + +[card] +

Customer Details

+

Name: {customer_name}
+Email: {customer_email}
+Phone: {customer_phone}

+[/card] + +[card] +

View Order Details

+[/card]', 'woonoow'), 'variables' => self::get_order_variables(), 'wc_email_id' => 'WC_Email_New_Order', ], @@ -151,7 +170,26 @@ class TemplateProvider { 'event_id' => 'order_processing', 'channel_id' => 'email', 'subject' => $wc_processing['subject'] ?? __('Your order #{order_number} is being processed', 'woonoow'), - 'body' => __("Hi {customer_name},\n\nThank you for your order! We're now processing it.\n\nOrder Number: {order_number}\nOrder Total: {order_total}\nPayment Method: {payment_method}\n\nYou can track your order here: {order_url}\n\nBest regards,\n{store_name}", 'woonoow'), + 'body' => __('[card type="success"] +

✅ Order Confirmed!

+

Hi {customer_name},

+

Thank you for your order! We\'re now processing it and will notify you once it ships.

+[/card] + +[card] +

Order Summary

+
+

Order #{order_number}

+

Total: {order_total}

+

Payment: {payment_method}

+
+{order_items} +[/card] + +[card] +

Track Your Order

+

Questions? Reply to this email or contact us.

+[/card]', 'woonoow'), 'variables' => self::get_order_variables(), 'wc_email_id' => 'WC_Email_Customer_Processing_Order', ], diff --git a/templates/emails/base.html b/templates/emails/base.html new file mode 100644 index 0000000..434cdde --- /dev/null +++ b/templates/emails/base.html @@ -0,0 +1,363 @@ + + + + + + + + + + {{email_subject}} + + + + + + +
+ + + + + + + + + + + + + + + + + + + + +
+ +