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 ) );
?>
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;
}
}