403 lines
16 KiB
PHP
403 lines
16 KiB
PHP
<?php
|
|
if (!defined('ABSPATH')) {
|
|
exit;
|
|
}
|
|
|
|
class ON_Email_Manager
|
|
{
|
|
|
|
public static function init()
|
|
{
|
|
add_action('on_send_booking_email', array(__CLASS__, 'process_booking_email'));
|
|
}
|
|
|
|
public static function queue_booking_confirmation($booking_id)
|
|
{
|
|
// Schedule the event to run immediately (async)
|
|
wp_schedule_single_event(time(), 'on_send_booking_email', array($booking_id));
|
|
}
|
|
|
|
public static function process_booking_email($booking_id)
|
|
{
|
|
// This runs in the background
|
|
$post = get_post($booking_id);
|
|
if (!$post || $post->post_type !== 'on_booking') {
|
|
return false;
|
|
}
|
|
|
|
// Check if emails are enabled
|
|
if (!get_option('on_booking_enable_emails', 0)) {
|
|
return false;
|
|
}
|
|
|
|
// Get Booking Data
|
|
$date = get_post_meta($booking_id, 'on_booking_date', true);
|
|
$time = get_post_meta($booking_id, 'on_booking_time', true);
|
|
$service = get_post_meta($booking_id, 'on_booking_service_name', true);
|
|
$email = get_post_meta($booking_id, 'on_booking_email', true);
|
|
$tracking_id = get_post_meta($booking_id, 'on_booking_tracking_id', true);
|
|
|
|
// Get Name from Title "YYYY-MM-DD - HH:MM (Name)"
|
|
$title_parts = explode('(', $post->post_title);
|
|
$customer_name = isset($title_parts[1]) ? rtrim($title_parts[1], ')') : 'Kunde';
|
|
|
|
// Get Template
|
|
$subject = get_option('on_booking_email_subject', 'Buchungsbestätigung: {service} am {date}');
|
|
$body = get_option('on_booking_email_body', '<h3>Hallo {name},</h3><p>vielen Dank für deine Buchung.</p>');
|
|
|
|
// Replace Placeholders
|
|
$placeholders = array(
|
|
'{name}' => $customer_name,
|
|
'{date}' => $date,
|
|
'{time}' => $time,
|
|
'{service}' => $service,
|
|
'{tracking_id}' => $tracking_id
|
|
);
|
|
|
|
foreach ($placeholders as $key => $value) {
|
|
$subject = str_replace($key, $value, $subject);
|
|
$body = str_replace($key, $value, $body);
|
|
}
|
|
|
|
// Send customer email
|
|
self::send_email($email, $subject, $body);
|
|
}
|
|
|
|
/**
|
|
* Send a notification email to the workshop with all booking details.
|
|
*/
|
|
public static function send_admin_notification($booking_id, $name, $customer_email, $date, $time, $service, $tracking_id, $attachment_path = '')
|
|
{
|
|
if (!get_option('on_booking_enable_admin_notify', 0)) {
|
|
return;
|
|
}
|
|
|
|
$admin_email = get_option('on_booking_admin_notify_email', '');
|
|
if (empty($admin_email) || !is_email($admin_email)) {
|
|
return;
|
|
}
|
|
|
|
// Get extra booking data from post
|
|
$post = get_post($booking_id);
|
|
$phone = get_post_meta($booking_id, 'on_booking_phone', true);
|
|
$status = get_post_meta($booking_id, 'on_booking_status', true);
|
|
$customer_request = get_post_meta($booking_id, 'on_booking_customer_request', true);
|
|
$notes = $post ? $post->post_content : '';
|
|
|
|
// Parse vehicle info from post content
|
|
$brand = '';
|
|
$year = '';
|
|
$description = '';
|
|
if ($notes) {
|
|
if (preg_match('/Fahrzeug:\s*(.+?)\s*\((\d{4})\)/m', $notes, $m)) {
|
|
$brand = $m[1];
|
|
$year = $m[2];
|
|
}
|
|
if (preg_match('/Beschreibung:\s*(.+)/m', $notes, $m)) {
|
|
$description = trim($m[1]);
|
|
}
|
|
}
|
|
|
|
$status_labels = array(
|
|
'waiting' => 'Warten auf Bestätigung',
|
|
'confirmed' => 'Bestätigt',
|
|
'in_progress' => 'In Arbeit',
|
|
'done' => 'Abgeschlossen',
|
|
'cancelled' => 'Storniert',
|
|
);
|
|
$status_display = isset($status_labels[$status]) ? $status_labels[$status] : ucfirst($status);
|
|
|
|
// Detect if this is a simple mode request
|
|
$is_simple = ($service === 'Offene Anfrage');
|
|
|
|
// Format date for display
|
|
$date_display = $date;
|
|
$time_display = $time;
|
|
|
|
// Build nicely formatted HTML email
|
|
if ($is_simple) {
|
|
$subject = 'Neue Anfrage von ' . $name . ' am ' . $date;
|
|
} else {
|
|
$subject = 'Neue Buchung: ' . $service . ' am ' . $date . ' um ' . $time;
|
|
}
|
|
|
|
$heading = $is_simple ? 'Neue Anfrage eingegangen' : 'Neue Buchung eingegangen';
|
|
$body = '<h2 style="color: #0061ff; margin-bottom: 5px;">' . $heading . '</h2>';
|
|
$body .= '<p style="color: #888; margin-top: 0;">Auftragsnummer: <strong style="font-family: monospace; color: #0061ff;">' . esc_html($tracking_id) . '</strong></p>';
|
|
|
|
// Customer Request (simple mode)
|
|
if ($customer_request) {
|
|
$body .= '<table style="width: 100%; border-collapse: collapse; margin: 15px 0;">';
|
|
$body .= '<tr style="background: #e65100; color: #fff;"><th colspan="2" style="padding: 10px; text-align: left; font-size: 1.1em;">Kundenwunsch</th></tr>';
|
|
$body .= '<tr><td style="padding: 12px 10px; border-bottom: 1px solid #eee;" colspan="2">' . nl2br(esc_html($customer_request)) . '</td></tr>';
|
|
$body .= '</table>';
|
|
}
|
|
|
|
// Customer Info
|
|
$body .= '<table style="width: 100%; border-collapse: collapse; margin: 15px 0;">';
|
|
$body .= '<tr style="background: #1a1a2e; color: #fff;"><th colspan="2" style="padding: 10px; text-align: left; font-size: 1.1em;">Kundendaten</th></tr>';
|
|
$body .= '<tr><td style="padding: 8px 10px; border-bottom: 1px solid #eee; font-weight: bold; width: 140px;">Name</td><td style="padding: 8px 10px; border-bottom: 1px solid #eee;">' . esc_html($name) . '</td></tr>';
|
|
$body .= '<tr><td style="padding: 8px 10px; border-bottom: 1px solid #eee; font-weight: bold;">E-Mail</td><td style="padding: 8px 10px; border-bottom: 1px solid #eee;"><a href="mailto:' . esc_attr($customer_email) . '" style="color: #0061ff;">' . esc_html($customer_email) . '</a></td></tr>';
|
|
if ($phone) {
|
|
$body .= '<tr><td style="padding: 8px 10px; border-bottom: 1px solid #eee; font-weight: bold;">Telefon</td><td style="padding: 8px 10px; border-bottom: 1px solid #eee;"><a href="tel:' . esc_attr($phone) . '" style="color: #0061ff;">' . esc_html($phone) . '</a></td></tr>';
|
|
}
|
|
$body .= '</table>';
|
|
|
|
// Booking Details
|
|
$body .= '<table style="width: 100%; border-collapse: collapse; margin: 15px 0;">';
|
|
$body .= '<tr style="background: #0061ff; color: #fff;"><th colspan="2" style="padding: 10px; text-align: left; font-size: 1.1em;">Buchungsdetails</th></tr>';
|
|
$body .= '<tr><td style="padding: 8px 10px; border-bottom: 1px solid #eee; font-weight: bold; width: 140px;">Service</td><td style="padding: 8px 10px; border-bottom: 1px solid #eee;">' . esc_html($service) . '</td></tr>';
|
|
$body .= '<tr><td style="padding: 8px 10px; border-bottom: 1px solid #eee; font-weight: bold;">Datum</td><td style="padding: 8px 10px; border-bottom: 1px solid #eee;">' . esc_html($date_display) . '</td></tr>';
|
|
if (!$is_simple) {
|
|
$body .= '<tr><td style="padding: 8px 10px; border-bottom: 1px solid #eee; font-weight: bold;">Uhrzeit</td><td style="padding: 8px 10px; border-bottom: 1px solid #eee;">' . esc_html($time_display) . '</td></tr>';
|
|
}
|
|
$body .= '<tr><td style="padding: 8px 10px; border-bottom: 1px solid #eee; font-weight: bold;">Status</td><td style="padding: 8px 10px; border-bottom: 1px solid #eee;">' . esc_html($status_display) . '</td></tr>';
|
|
$body .= '</table>';
|
|
|
|
// Vehicle Info
|
|
if ($brand || $year) {
|
|
$body .= '<table style="width: 100%; border-collapse: collapse; margin: 15px 0;">';
|
|
$body .= '<tr style="background: #333; color: #fff;"><th colspan="2" style="padding: 10px; text-align: left; font-size: 1.1em;">Fahrzeug</th></tr>';
|
|
if ($brand) {
|
|
$body .= '<tr><td style="padding: 8px 10px; border-bottom: 1px solid #eee; font-weight: bold; width: 140px;">Marke/Modell</td><td style="padding: 8px 10px; border-bottom: 1px solid #eee;">' . esc_html($brand) . '</td></tr>';
|
|
}
|
|
if ($year) {
|
|
$body .= '<tr><td style="padding: 8px 10px; border-bottom: 1px solid #eee; font-weight: bold;">Baujahr</td><td style="padding: 8px 10px; border-bottom: 1px solid #eee;">' . esc_html($year) . '</td></tr>';
|
|
}
|
|
if ($description) {
|
|
$body .= '<tr><td style="padding: 8px 10px; border-bottom: 1px solid #eee; font-weight: bold;">Beschreibung</td><td style="padding: 8px 10px; border-bottom: 1px solid #eee;">' . esc_html($description) . '</td></tr>';
|
|
}
|
|
$body .= '</table>';
|
|
}
|
|
|
|
$body .= '<p style="color: #888; font-size: 0.9em; margin-top: 20px;">Diese E-Mail wurde automatisch vom Buchungssystem gesendet.</p>';
|
|
|
|
$attachments = array();
|
|
if ($attachment_path && file_exists($attachment_path)) {
|
|
$attachments[] = $attachment_path;
|
|
}
|
|
|
|
self::send_email($admin_email, $subject, $body, false, $attachments);
|
|
}
|
|
|
|
public static function send_test_email($to_email)
|
|
{
|
|
// 1. Pre-check Connection
|
|
$check = self::test_smtp_connection();
|
|
if ($check !== true) {
|
|
return $check; // Returns error string
|
|
}
|
|
|
|
$subject = 'Test E-Mail: ON Motorrad Buchung';
|
|
$body = '<h3>Test erfolgreich!</h3><p>Dies ist eine Test-Nachricht von deinem Buchungssystem. Wenn du diese Nachricht liest, funktionieren die SMTP-Einstellungen.</p>';
|
|
|
|
// Call with debug = true
|
|
$result = self::send_email($to_email, $subject, $body, true);
|
|
|
|
if (is_array($result)) {
|
|
$log = $result['log'];
|
|
$status = $result['result'] ? 'ERFOLG' : 'FEHLER';
|
|
return "$status. Full Log:\n\n" . $log;
|
|
}
|
|
|
|
if ($result) {
|
|
return true;
|
|
} else {
|
|
return 'WP Mail returned false (Check Mail Log if available)';
|
|
}
|
|
}
|
|
|
|
private static function test_smtp_connection()
|
|
{
|
|
$host = get_option('on_booking_smtp_host');
|
|
$port = get_option('on_booking_smtp_port', 587);
|
|
|
|
if (!$host) {
|
|
return 'SMTP Host fehlt.';
|
|
}
|
|
|
|
// 3 Seconds Timeout for Connection Test
|
|
$connection = @fsockopen($host, $port, $errno, $errstr, 3);
|
|
|
|
if (is_resource($connection)) {
|
|
fclose($connection);
|
|
return true;
|
|
} else {
|
|
return "Verbindung zu $host:$port fehlgeschlagen. ($errno: $errstr)";
|
|
}
|
|
}
|
|
|
|
private static function send_email($to, $subject, $body, $debug = false, $attachments = array())
|
|
{
|
|
// Get SMTP Settings
|
|
$smtp_host = get_option('on_booking_smtp_host');
|
|
$smtp_port = get_option('on_booking_smtp_port', 587);
|
|
// $smtp_user = trim(get_option('on_booking_smtp_user'));
|
|
// $smtp_pass = trim(get_option('on_booking_smtp_pass'));
|
|
|
|
// DEBUG: Force provided credentials
|
|
$smtp_user = trim(get_option('on_booking_smtp_user'));
|
|
$smtp_pass = trim(get_option('on_booking_smtp_pass'));
|
|
$smtp_enc = get_option('on_booking_smtp_enc', 'tls');
|
|
$smtp_auth_type = get_option('on_booking_smtp_auth_type', 'auto');
|
|
$mail_method = get_option('on_booking_mail_method', 'smtp');
|
|
$from_email = get_option('on_booking_from_email', get_bloginfo('admin_email'));
|
|
$from_name = get_option('on_booking_from_name', get_bloginfo('name'));
|
|
|
|
// Apply Premium Dark Styling Wrapper
|
|
$styled_body = self::apply_email_styling($body);
|
|
|
|
// Allow capturing debug output
|
|
$debug_output = "";
|
|
|
|
// PHPMailer Setup Hook
|
|
$phpmailer_hook = function ($phpmailer) use ($smtp_host, $smtp_port, $smtp_user, $smtp_pass, $smtp_enc, $smtp_auth_type, $mail_method, $from_email, $from_name, $debug, &$debug_output) {
|
|
if ($smtp_host && $mail_method === 'smtp') {
|
|
$phpmailer->isSMTP();
|
|
$phpmailer->Host = $smtp_host;
|
|
$phpmailer->SMTPAuth = true;
|
|
$phpmailer->Port = $smtp_port;
|
|
$phpmailer->Username = $smtp_user;
|
|
$phpmailer->Password = $smtp_pass;
|
|
|
|
// Map 'starttls' to 'tls' as PHPMailer uses 'tls' for STARTTLS
|
|
// And explicitly set SMTPSecure
|
|
if ($smtp_enc === 'starttls') {
|
|
$phpmailer->SMTPSecure = 'tls';
|
|
} elseif ($smtp_enc === 'ssl') {
|
|
$phpmailer->SMTPSecure = 'ssl';
|
|
} elseif ($smtp_enc === 'tls') {
|
|
$phpmailer->SMTPSecure = 'tls';
|
|
} else {
|
|
$phpmailer->SMTPSecure = '';
|
|
}
|
|
|
|
// Explicit Auth Type if requested
|
|
if ($smtp_auth_type && $smtp_auth_type !== 'auto') {
|
|
$phpmailer->AuthType = $smtp_auth_type;
|
|
}
|
|
|
|
// Set Timeout to prevent long hangs (User requested 30s)
|
|
$phpmailer->Timeout = 30;
|
|
$phpmailer->Timelimit = 30;
|
|
|
|
if ($debug) {
|
|
$phpmailer->SMTPDebug = 3; // Connection level + Data
|
|
$phpmailer->Debugoutput = function ($str, $level) use (&$debug_output) {
|
|
$debug_output .= "[$level] $str\n";
|
|
};
|
|
}
|
|
}
|
|
// Always set sender
|
|
$phpmailer->setFrom($from_email, $from_name);
|
|
$phpmailer->From = $from_email;
|
|
$phpmailer->FromName = $from_name;
|
|
};
|
|
|
|
add_action('phpmailer_init', $phpmailer_hook);
|
|
|
|
// Send headers
|
|
$headers = array('Content-Type: text/html; charset=UTF-8');
|
|
|
|
// Execute send
|
|
$result = wp_mail($to, $subject, $styled_body, $headers, $attachments);
|
|
|
|
// Remove hook to avoid conflicts with other emails in same request
|
|
remove_action('phpmailer_init', $phpmailer_hook);
|
|
|
|
if ($debug) {
|
|
return array('result' => $result, 'log' => $debug_output);
|
|
}
|
|
|
|
return $result;
|
|
}
|
|
|
|
private static function apply_email_styling($content)
|
|
{
|
|
// Wrapper with dark theme consistent with plugin
|
|
ob_start();
|
|
?>
|
|
<!DOCTYPE html>
|
|
<html>
|
|
|
|
<head>
|
|
<style>
|
|
body {
|
|
margin: 0;
|
|
padding: 0;
|
|
font-family: 'Helvetica', 'Arial', sans-serif;
|
|
background-color: #111111;
|
|
color: #ffffff;
|
|
}
|
|
|
|
.email-container {
|
|
max-width: 600px;
|
|
margin: 0 auto;
|
|
background-color: #1f1f1f;
|
|
overflow: hidden;
|
|
}
|
|
|
|
.email-header {
|
|
background-color: #0061ff;
|
|
padding: 20px;
|
|
text-align: center;
|
|
}
|
|
|
|
.email-header h1 {
|
|
margin: 0;
|
|
color: #ffffff;
|
|
font-style: italic;
|
|
text-transform: uppercase;
|
|
transform: skewX(-10deg);
|
|
}
|
|
|
|
.email-content {
|
|
padding: 30px;
|
|
color: #dddddd;
|
|
line-height: 1.6;
|
|
}
|
|
|
|
.email-footer {
|
|
background-color: #111111;
|
|
padding: 20px;
|
|
text-align: center;
|
|
font-size: 12px;
|
|
color: #666666;
|
|
}
|
|
|
|
a {
|
|
color: #0061ff;
|
|
text-decoration: none;
|
|
}
|
|
|
|
h2,
|
|
h3 {
|
|
color: #ffffff;
|
|
margin-top: 0;
|
|
font-size: 1.25em;
|
|
}
|
|
</style>
|
|
</head>
|
|
|
|
<body>
|
|
<div class="email-container">
|
|
<div class="email-header">
|
|
<h1>Buchung <span>Bestätigt</span></h1>
|
|
</div>
|
|
<div class="email-content">
|
|
<?php echo wp_kses_post($content); ?>
|
|
</div>
|
|
<div class="email-footer">
|
|
©
|
|
<?php echo date('Y'); ?>
|
|
<?php echo get_bloginfo('name'); ?>
|
|
</div>
|
|
</div>
|
|
</body>
|
|
|
|
</html>
|
|
<?php
|
|
return ob_get_clean();
|
|
}
|
|
}
|