ticket_number, $ticket->subject ); $body = array( 'Ein neues Support-Ticket wurde erstellt.', '', 'Ticket: ' . $ticket->ticket_number, 'Kunde: ' . ( $ticket->customer_name ?: '—' ), 'E-Mail: ' . ( $ticket->customer_email ?: '—' ), 'Betreff: ' . $ticket->subject, ); if ( $message ) { $body[] = ''; $body[] = 'Nachricht:'; $body[] = self::message_excerpt( $message->body ); } $body[] = ''; $body[] = 'Ticket im Backend öffnen:'; $body[] = self::admin_ticket_url( $ticket->id ); return self::send( self::staff_recipients(), $subject, implode( "\n", $body ) ); } public static function notify_staff_customer_reply( $ticket_id, $message_id ) { if ( ! self::option_enabled( 'dpsupport_notify_staff_customer_reply', true ) ) { return false; } $ticket = self::get_ticket( $ticket_id ); $message = self::get_message( $message_id ); if ( ! $ticket || ! $message ) { return false; } $subject = sprintf( '[%1$s Support] Neue Kundenantwort %2$s – %3$s', self::site_name(), $ticket->ticket_number, $ticket->subject ); $body = array( 'Ein Kunde hat auf ein Support-Ticket geantwortet.', '', 'Ticket: ' . $ticket->ticket_number, 'Kunde: ' . ( $ticket->customer_name ?: '—' ), 'Betreff: ' . $ticket->subject, '', 'Antwort:', self::message_excerpt( $message->body ), '', 'Ticket im Backend öffnen:', self::admin_ticket_url( $ticket->id ), ); return self::send( self::staff_recipients(), $subject, implode( "\n", $body ) ); } public static function notify_customer_staff_reply( $ticket_id, $message_id ) { $result = self::notify_customer_staff_reply_detailed( $ticket_id, $message_id ); return ! empty( $result['sent'] ); } public static function notify_customer_staff_reply_detailed( $ticket_id, $message_id ) { if ( ! self::option_enabled( 'dpsupport_notify_customer_staff_reply', true ) ) { return array( 'sent' => false, 'message' => __( 'Kundenbenachrichtigung ist deaktiviert.', '24laser-support-tickets' ) ); } $ticket = self::get_ticket( $ticket_id ); $message = self::get_message( $message_id ); if ( ! $ticket || ! $message ) { return array( 'sent' => false, 'message' => __( 'Ticket oder Nachricht wurde nicht gefunden.', '24laser-support-tickets' ) ); } $recipient = self::resolve_customer_recipient( $ticket ); if ( ! $recipient ) { return array( 'sent' => false, 'message' => __( 'Keine gültige Kunden-E-Mail-Adresse vorhanden.', '24laser-support-tickets' ) ); } $subject = sprintf( '[%1$s Support] Antwort zu %2$s – %3$s', self::site_name(), $ticket->ticket_number, $ticket->subject ); $body = array( 'Hallo ' . ( $ticket->customer_name ?: '' ) . ',', '', 'unser Support-Team hat auf dein Ticket ' . $ticket->ticket_number . ' geantwortet.', '', wp_strip_all_tags( (string) $message->body ), ); $url = self::customer_ticket_url( $ticket ); if ( $url ) { $body[] = ''; $body[] = 'Ticket ansehen / antworten:'; $body[] = $url; } $body[] = ''; $body[] = 'Viele Grüße'; $body[] = self::site_name(); $result = self::send_detailed( array( $recipient ), $subject, implode( "\n", $body ) ); return array( 'sent' => ! empty( $result['sent'] ), 'recipient' => $recipient, 'message' => ! empty( $result['sent'] ) ? __( 'Kundenbenachrichtigung wurde versendet.', '24laser-support-tickets' ) : ( $result['error'] ?? __( 'Kundenbenachrichtigung konnte nicht versendet werden.', '24laser-support-tickets' ) ), ); } public static function notify_customer_ticket_created( $ticket_id, $message_id = 0, $created_by_customer = false ) { unset( $message_id, $created_by_customer ); if ( ! self::option_enabled( 'dpsupport_notify_customer_ticket_created', true ) ) { return false; } $ticket = self::get_ticket( $ticket_id ); if ( ! $ticket ) { return false; } $recipient = self::resolve_customer_recipient( $ticket ); if ( ! $recipient ) { return false; } $subject = sprintf( '[%1$s Support] Ticket %2$s eingegangen', self::site_name(), $ticket->ticket_number ); $body = array( 'Hallo ' . ( $ticket->customer_name ?: '' ) . ',', '', 'deine Support-Anfrage ist bei uns eingegangen.', '', 'Ticket: ' . $ticket->ticket_number, 'Betreff: ' . $ticket->subject, ); $url = self::customer_ticket_url( $ticket ); if ( $url ) { $body[] = ''; $body[] = 'Ticket ansehen / antworten:'; $body[] = $url; } $body[] = ''; $body[] = 'Viele Grüße'; $body[] = self::site_name(); return self::send( array( $recipient ), $subject, implode( "\n", $body ) ); } public static function send_guest_access_link_detailed( $ticket_id ) { $ticket = self::get_ticket( $ticket_id ); if ( ! $ticket || ! empty( $ticket->customer_id ) ) { return array( 'sent' => false, 'message' => __( 'Dieses Ticket ist kein Gastticket.', '24laser-support-tickets' ) ); } $recipient = self::resolve_customer_recipient( $ticket ); $url = DPSUPPORT_Guest_Ticket_Access::ticket_url( $ticket ); if ( ! $recipient || ! $url ) { return array( 'sent' => false, 'message' => __( 'Gastzugang konnte nicht erzeugt werden.', '24laser-support-tickets' ) ); } $subject = sprintf( '[%1$s Support] Zugang zu Ticket %2$s', self::site_name(), $ticket->ticket_number ); $body = array( 'Hallo ' . ( $ticket->customer_name ?: '' ) . ',', '', 'hier ist dein persönlicher Zugang zum Support-Ticket ' . $ticket->ticket_number . '.', '', $url, '', 'Bitte behandle diesen persönlichen Link vertraulich.', ); $result = self::send_detailed( array( $recipient ), $subject, implode( "\n", $body ) ); return array( 'sent' => ! empty( $result['sent'] ), 'recipient' => $recipient, 'message' => ! empty( $result['sent'] ) ? __( 'Gastzugangslink wurde versendet.', '24laser-support-tickets' ) : ( $result['error'] ?? __( 'Gastzugangslink konnte nicht versendet werden.', '24laser-support-tickets' ) ), ); } public static function send_test_email( $recipient ) { $recipient = sanitize_email( $recipient ); if ( ! $recipient || ! is_email( $recipient ) ) { return array( 'sent' => false, 'message' => __( 'Bitte gib eine gültige E-Mail-Adresse ein.', '24laser-support-tickets' ) ); } $result = self::send_detailed( array( $recipient ), sprintf( '[%s Support] Test-E-Mail', self::site_name() ), "24laser Support Tickets Free\n\nDer WordPress-Mailversand funktioniert für diese Testnachricht." ); return array( 'sent' => ! empty( $result['sent'] ), 'message' => ! empty( $result['sent'] ) ? __( 'Test-E-Mail wurde versendet.', '24laser-support-tickets' ) : ( $result['error'] ?? __( 'Test-E-Mail konnte nicht versendet werden.', '24laser-support-tickets' ) ), ); } private static function get_ticket( $ticket_id ) { return ( new DPSUPPORT_Ticket_Repository() )->get( absint( $ticket_id ) ); } private static function get_message( $message_id ) { return ( new DPSUPPORT_Message_Repository() )->get( absint( $message_id ) ); } private static function staff_recipients() { $raw = (string) get_option( 'dpsupport_notification_email', get_option( 'admin_email', '' ) ); $parts = preg_split( '/[;,\s]+/', $raw ); $valid = array(); foreach ( (array) $parts as $email ) { $email = sanitize_email( $email ); if ( $email && is_email( $email ) ) { $valid[ strtolower( $email ) ] = $email; } } return array_values( $valid ); } private static function resolve_customer_recipient( $ticket ) { if ( ! is_object( $ticket ) ) { return ''; } $email = sanitize_email( (string) ( $ticket->customer_email ?? '' ) ); if ( $email && is_email( $email ) ) { return $email; } if ( ! empty( $ticket->customer_id ) ) { $user = get_user_by( 'id', absint( $ticket->customer_id ) ); if ( $user && is_email( $user->user_email ) ) { return sanitize_email( $user->user_email ); } } return ''; } private static function send_detailed( array $recipients, $subject, $body ) { $recipients = array_values( array_filter( array_unique( array_map( 'sanitize_email', $recipients ) ), 'is_email' ) ); if ( ! $recipients ) { return array( 'sent' => false, 'error' => __( 'Keine gültige Empfängeradresse vorhanden.', '24laser-support-tickets' ), 'transport' => 'wordpress' ); } $subject = str_replace( array( "\r", "\n" ), '', wp_strip_all_tags( (string) $subject ) ); $headers = array( 'Content-Type: text/plain; charset=UTF-8', 'X-24laser-Support-System: outbound' ); $from_email = self::support_from_email(); $from_name = self::support_from_name(); $reply_to = self::support_reply_to_email(); if ( $from_email ) { $headers[] = 'From: ' . self::format_mailbox_header( $from_name, $from_email ); } if ( $reply_to ) { $headers[] = 'Reply-To: ' . self::format_mailbox_header( $from_name, $reply_to ); } $captured_error = ''; $failure_callback = static function ( $error ) use ( &$captured_error ) { if ( is_wp_error( $error ) ) { $captured_error = $error->get_error_message(); } }; add_action( 'wp_mail_failed', $failure_callback, 999, 1 ); try { $sent = (bool) wp_mail( $recipients, $subject, (string) $body, $headers ); } catch ( Throwable $error ) { $sent = false; $captured_error = $error->getMessage(); } finally { remove_action( 'wp_mail_failed', $failure_callback, 999 ); } return array( 'sent' => $sent, 'error' => $sent ? '' : sanitize_text_field( $captured_error ?: __( 'wp_mail() hat false zurückgegeben.', '24laser-support-tickets' ) ), 'transport' => 'wordpress', ); } private static function support_from_email() { foreach ( array( get_option( 'dpsupport_support_from_email', '' ), get_option( 'admin_email', '' ) ) as $candidate ) { $email = sanitize_email( (string) $candidate ); if ( $email && is_email( $email ) ) { return $email; } } return ''; } private static function support_reply_to_email() { $email = sanitize_email( (string) get_option( 'dpsupport_support_reply_to_email', '' ) ); return $email && is_email( $email ) ? $email : self::support_from_email(); } private static function support_from_name() { $name = sanitize_text_field( (string) get_option( 'dpsupport_support_from_name', self::site_name() . ' Support' ) ); return $name ?: self::site_name() . ' Support'; } private static function format_mailbox_header( $name, $email ) { $name = str_replace( array( "\r", "\n", '"' ), '', sanitize_text_field( $name ) ); $email = sanitize_email( $email ); return $name ? sprintf( '"%s" <%s>', $name, $email ) : $email; } private static function send( array $recipients, $subject, $body ) { $result = self::send_detailed( $recipients, $subject, $body ); return ! empty( $result['sent'] ); } private static function option_enabled( $name, $default = true ) { return 'yes' === get_option( $name, $default ? 'yes' : 'no' ); } private static function message_excerpt( $body ) { $text = trim( wp_strip_all_tags( (string) $body ) ); return mb_strlen( $text ) > 1200 ? mb_substr( $text, 0, 1200 ) . '…' : $text; } private static function admin_ticket_url( $ticket_id ) { return add_query_arg( array( 'page' => 'dpsupport-support', 'ticket_id' => absint( $ticket_id ) ), admin_url( 'admin.php' ) ); } private static function customer_ticket_url( $ticket ) { if ( ! is_object( $ticket ) ) { return ''; } if ( empty( $ticket->customer_id ) ) { return DPSUPPORT_Guest_Ticket_Access::ticket_url( $ticket ); } if ( function_exists( 'wc_get_account_endpoint_url' ) ) { return add_query_arg( 'dpsupport_ticket', absint( $ticket->id ), wc_get_account_endpoint_url( 'support' ) ); } return ''; } private static function site_name() { return wp_specialchars_decode( (string) get_bloginfo( 'name' ), ENT_QUOTES ); } }