tickets = $tickets; $this->messages = $messages; $this->attachments = $attachments; $this->activity = $activity; $this->woocommerce = $woocommerce; } public function init() { add_action( 'init', array( $this, 'register_endpoint' ), 10 ); add_filter( 'woocommerce_get_query_vars', array( $this, 'register_wc_query_var' ) ); add_filter( 'woocommerce_account_menu_items', array( $this, 'add_account_menu_item' ), 40 ); add_action( 'woocommerce_account_dpsupport_endpoint', array( $this, 'render_endpoint' ) ); add_action( 'template_redirect', array( $this, 'handle_customer_post' ) ); add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_assets' ) ); } public function register_endpoint() { if ( function_exists( 'add_rewrite_endpoint' ) ) { add_rewrite_endpoint( 'dpsupport', EP_ROOT | EP_PAGES ); } } public function register_wc_query_var( $vars ) { $vars['dpsupport'] = 'dpsupport'; return $vars; } public function add_account_menu_item( $items ) { if ( ! $this->woocommerce->is_available() ) { return $items; } $logout = isset( $items['customer-logout'] ) ? $items['customer-logout'] : null; unset( $items['customer-logout'] ); $items['dpsupport'] = __( 'Support', '24laser-support-tickets' ); if ( null !== $logout ) { $items['customer-logout'] = $logout; } return $items; } public function enqueue_assets() { if ( ! $this->woocommerce->is_available() || ! function_exists( 'is_account_page' ) || ! is_account_page() ) { return; } wp_enqueue_style( 'dpsupport-customer', DPSUPPORT_URL . 'assets/css/customer.css', array(), DPSUPPORT_VERSION ); } public function render_endpoint() { if ( ! is_user_logged_in() ) { echo '

' . esc_html__( 'Bitte melde dich an, um den Supportbereich zu verwenden.', '24laser-support-tickets' ) . '

'; return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only ticket navigation; ownership is checked before rendering. $ticket_id = isset( $_GET['dpsupport_ticket'] ) ? absint( $_GET['dpsupport_ticket'] ) : 0; if ( $ticket_id ) { $this->render_ticket( $ticket_id ); return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only navigation flag; no state change occurs here. if ( ! empty( $_GET['dpsupport_new'] ) ) { $this->render_new_ticket_form(); return; } $this->render_ticket_list(); } private function render_ticket_list() { $user = wp_get_current_user(); // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Read-only pagination value; no state change occurs. $paged = isset( $_GET['dpsupport_page'] ) ? max( 1, absint( $_GET['dpsupport_page'] ) ) : 1; $per_page = 25; $total = $this->tickets->count_for_customer( $user->ID, $user->user_email ); $tickets = $this->tickets->get_for_customer( $user->ID, $user->user_email, $per_page, $paged ); $statuses = $this->tickets->statuses(); $total_pages = max( 1, (int) ceil( $total / $per_page ) ); ?>

subject ); ?>ticket_number ); ?>
status ] ?? $ticket->status ); ?>updated_at ) ); ?>
1 ) : ?>

tickets->get( $ticket_id ); if ( ! $this->tickets->customer_owns_ticket( $ticket, $user->ID, $user->user_email ) ) { echo '
' . esc_html__( 'Dieses Ticket gehört nicht zu deinem Kundenkonto.', '24laser-support-tickets' ) . '
'; return; } $messages = $this->messages->get_public_for_ticket( $ticket_id ); $statuses = $this->tickets->statuses(); $attachment_map = array(); foreach ( (array) $this->attachments->get_for_ticket( $ticket_id ) as $attachment ) { $message_id = absint( $attachment->message_id ?? 0 ); if ( $message_id ) { $attachment_map[ $message_id ][] = absint( $attachment->attachment_id ?? 0 ); } } $can_reply = empty( $ticket->archived_at ) && 'closed' !== $ticket->status; ?>

subject ); ?>

ticket_number ); ?> · status ] ?? $ticket->status ); ?>

author_type ? ( $message->author_name ?: __( 'Du', '24laser-support-tickets' ) ) : ( $message->author_name ?: __( 'Support', '24laser-support-tickets' ) ) ); ?>created_at ) ); ?>
body ) ); ?>
id ] ) ) : ?>
id ] as $attachment_id ) : $url = wp_get_attachment_url( $attachment_id ); if ( ! $url ) { continue; } ?>

handle_create_ticket(); } elseif ( 'reply_ticket' === $action ) { $this->handle_reply_ticket(); } } private function handle_create_ticket() { if ( ! isset( $_POST['dpsupport_customer_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['dpsupport_customer_nonce'] ) ), 'dpsupport_customer_create_ticket' ) ) { wc_add_notice( __( 'Die Anfrage konnte nicht sicher geprüft werden.', '24laser-support-tickets' ), 'error' ); $this->redirect( array( 'dpsupport_new' => 1 ) ); } $user = wp_get_current_user(); $subject = sanitize_text_field( wp_unslash( $_POST['subject'] ?? '' ) ); $message = wp_kses_post( wp_unslash( $_POST['message'] ?? '' ) ); if ( '' === trim( $subject ) || '' === trim( wp_strip_all_tags( $message ) ) ) { wc_add_notice( __( 'Bitte gib einen Betreff und eine Nachricht ein.', '24laser-support-tickets' ), 'error' ); $this->redirect( array( 'dpsupport_new' => 1 ) ); } $name = trim( get_user_meta( $user->ID, 'billing_first_name', true ) . ' ' . get_user_meta( $user->ID, 'billing_last_name', true ) ); if ( '' === $name ) { $name = $user->display_name; } $ticket_id = $this->tickets->create( array( 'customer_id' => $user->ID, 'customer_name' => $name, 'customer_email' => $user->user_email, 'subject' => $subject, 'category' => get_option( 'dpsupport_default_category', 'allgemein' ), 'status' => 'new', 'priority' => get_option( 'dpsupport_default_priority', 'normal' ), ) ); if ( is_wp_error( $ticket_id ) ) { wc_add_notice( $ticket_id->get_error_message(), 'error' ); $this->redirect( array( 'dpsupport_new' => 1 ) ); } $message_id = $this->messages->create( $ticket_id, array( 'author_type' => 'customer', 'author_user_id' => $user->ID, 'author_name' => $name, 'body' => $message, 'is_internal' => 0 ) ); if ( is_wp_error( $message_id ) ) { $this->tickets->delete_permanently( $ticket_id ); wc_add_notice( $message_id->get_error_message(), 'error' ); $this->redirect( array( 'dpsupport_new' => 1 ) ); } $this->activity->add( $ticket_id, 'customer_created', __( 'Kunde hat das Ticket über sein Kundenkonto erstellt.', '24laser-support-tickets' ), $user->ID ); $upload_errors = $this->handle_uploads( $ticket_id, $message_id ); DPSUPPORT_Notifications::notify_staff_new_ticket( $ticket_id, $message_id ); DPSUPPORT_Notifications::notify_customer_ticket_created( $ticket_id, $message_id, true ); do_action( 'dpsupport_ticket_created', $ticket_id, 'customer_portal' ); wc_add_notice( $upload_errors ? __( 'Das Ticket wurde erstellt, aber der Anhang konnte nicht hochgeladen werden.', '24laser-support-tickets' ) : __( 'Deine Support-Anfrage wurde erfolgreich gesendet.', '24laser-support-tickets' ), $upload_errors ? 'notice' : 'success' ); $this->redirect( array( 'dpsupport_ticket' => $ticket_id ) ); } private function handle_reply_ticket() { $ticket_id = absint( $_POST['ticket_id'] ?? 0 ); if ( ! isset( $_POST['dpsupport_customer_nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['dpsupport_customer_nonce'] ) ), 'dpsupport_customer_reply_' . $ticket_id ) ) { wc_add_notice( __( 'Die Antwort konnte nicht sicher geprüft werden.', '24laser-support-tickets' ), 'error' ); $this->redirect( array( 'dpsupport_ticket' => $ticket_id ) ); } $user = wp_get_current_user(); $ticket = $this->tickets->get( $ticket_id ); if ( ! $this->tickets->customer_owns_ticket( $ticket, $user->ID, $user->user_email ) ) { wc_add_notice( __( 'Dieses Ticket gehört nicht zu deinem Kundenkonto.', '24laser-support-tickets' ), 'error' ); $this->redirect(); } if ( ! empty( $ticket->archived_at ) || 'closed' === $ticket->status ) { wc_add_notice( __( 'Auf dieses Ticket kann nicht mehr geantwortet werden.', '24laser-support-tickets' ), 'error' ); $this->redirect( array( 'dpsupport_ticket' => $ticket_id ) ); } $message = wp_kses_post( wp_unslash( $_POST['message'] ?? '' ) ); if ( '' === trim( wp_strip_all_tags( $message ) ) ) { wc_add_notice( __( 'Bitte gib eine Nachricht ein.', '24laser-support-tickets' ), 'error' ); $this->redirect( array( 'dpsupport_ticket' => $ticket_id ) ); } $message_id = $this->messages->create( $ticket_id, array( 'author_type' => 'customer', 'author_user_id' => $user->ID, 'author_name' => $ticket->customer_name ?: $user->display_name, 'body' => $message, 'is_internal' => 0 ) ); if ( is_wp_error( $message_id ) ) { wc_add_notice( $message_id->get_error_message(), 'error' ); $this->redirect( array( 'dpsupport_ticket' => $ticket_id ) ); } $this->tickets->touch( $ticket_id ); $this->activity->add( $ticket_id, 'customer_reply', __( 'Kunde hat über sein Kundenkonto geantwortet.', '24laser-support-tickets' ), $user->ID ); $upload_errors = $this->handle_uploads( $ticket_id, $message_id ); DPSUPPORT_Notifications::notify_staff_customer_reply( $ticket_id, $message_id ); do_action( 'dpsupport_customer_replied', $ticket_id, $message_id ); wc_add_notice( $upload_errors ? __( 'Deine Antwort wurde gespeichert, aber der Anhang konnte nicht hochgeladen werden.', '24laser-support-tickets' ) : __( 'Deine Antwort wurde gesendet.', '24laser-support-tickets' ), $upload_errors ? 'notice' : 'success' ); $this->redirect( array( 'dpsupport_ticket' => $ticket_id ) ); } private function handle_uploads( $ticket_id, $message_id ) { return DPSUPPORT_Upload_Handler::handle( $ticket_id, $message_id, $this->attachments ) ? array() : array( 'upload_error' ); } private function support_url( $args = array() ) { $url = wc_get_account_endpoint_url( 'dpsupport' ); return $args ? add_query_arg( $args, $url ) : $url; } private function redirect( $args = array() ) { wp_safe_redirect( $this->support_url( $args ) ); exit; } }