Files
deskhub/DeskHub-Webseite/api/staff/v1/ticket.php
T
2026-10-16 19:12:13 +00:00

94 lines
4.2 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
declare(strict_types=1);
require_once __DIR__ . '/common.php';
api_require_method('GET');
$staff = api_require_staff();
$number = trim((string) ($_GET['number'] ?? ''));
if ($number === '') {
api_error(422, 'TICKET_NUMBER_REQUIRED', 'Eine Ticketnummer ist erforderlich.');
}
$pdo = get_db();
$ticket = api_find_ticket($pdo, $staff, $number);
// Generelle Ticket-Sperre (nicht Live-Chat-spezifisch, siehe ticket_locked_by_other()
// in includes/functions.php): wird von einem anderen Mitarbeiter (Web oder App) gerade
// frisch bearbeitet, wird das Ticket hier – anders als beim milderen Live-Chat-Lock
// weiter unten – gar nicht erst geladen, genau wie im Web-Backend (ticket_view.php).
if ($ticket['source'] !== 'chat') {
$lockedByName = ticket_locked_by_other($ticket, (int) $staff['id'], $pdo);
if ($lockedByName) {
api_error(409, 'TICKET_LOCKED', "Dieses Ticket wird gerade von \"$lockedByName\" bearbeitet und kann nicht gleichzeitig geöffnet werden.");
}
ticket_acquire_lock((int) $ticket['id'], (int) $staff['id'], $pdo);
}
$threadStmt = $pdo->prepare(
'SELECT tt.*, s.name AS staff_name, u.name AS user_name
FROM ticket_threads tt
LEFT JOIN staff s ON s.id = tt.staff_id
LEFT JOIN users u ON u.id = tt.user_id
WHERE tt.ticket_id = ?
ORDER BY tt.created_at ASC, tt.id ASC'
);
$threadStmt->execute([$ticket['id']]);
$attachmentStmt = $pdo->prepare(
'SELECT id, original_name, filesize FROM ticket_attachments WHERE thread_id = ? ORDER BY id'
);
$commentStmt = $pdo->prepare(
'SELECT tc.id, tc.message, tc.created_at, s.id AS staff_id, s.name AS staff_name
FROM ticket_thread_comments tc
JOIN staff s ON s.id = tc.staff_id
WHERE tc.thread_id = ? ORDER BY tc.created_at, tc.id'
);
$threads = [];
foreach ($threadStmt->fetchAll() as $row) {
$attachmentStmt->execute([$row['id']]);
$commentStmt->execute([$row['id']]);
$threads[] = [
'id' => (int) $row['id'],
'authorType' => $row['author_type'],
'authorName' => $row['staff_name'] ?: $row['user_name'] ?: $ticket['requester_name'],
'message' => api_plain_text($row['message']),
'isInternalNote' => (bool) $row['is_internal_note'],
'createdAt' => $row['created_at'],
'attachments' => array_map(fn(array $item) => [
'id' => (int) $item['id'],
'name' => $item['original_name'],
'size' => (int) $item['filesize'],
], $attachmentStmt->fetchAll()),
'comments' => array_map(fn(array $item) => [
'id' => (int) $item['id'],
'message' => api_plain_text($item['message']),
'staff' => ['id' => (int) $item['staff_id'], 'name' => $item['staff_name']],
'createdAt' => $item['created_at'],
], $commentStmt->fetchAll()),
];
}
// Live-Chat-Sperre: wie im Web-Backend (staff/live_chat.php) "besitzt" der Mitarbeiter,
// der den Chat gerade ansieht, ihn für ein paar Minuten – verhindert, dass App und Web
// gleichzeitig unbemerkt im selben Chat antworten. Nur für Live-Chat-Tickets relevant,
// normale Tickets bleiben unangetastet. Lesen bleibt für alle möglich, nur das
// Schreiben wird in api_add_ticket_message() serverseitig blockiert.
$lockedByOtherName = null;
if ($ticket['source'] === 'chat' && $ticket['status'] !== 'closed') {
$lockedByOtherName = live_chat_locked_by_other($ticket, (int) $staff['id'], $pdo);
if (!$lockedByOtherName) {
live_chat_acquire_lock((int) $ticket['id'], (int) $staff['id'], $pdo);
}
}
$summary = api_ticket_summary($ticket);
$summary['source'] = $ticket['source'];
$summary['firstResponseDueAt'] = $ticket['first_response_due_at'];
$summary['resolutionDueAt'] = $ticket['resolution_due_at'];
$summary['lockedByOtherName'] = $lockedByOtherName;
$summary['threads'] = $threads;
// Rechte für GENAU dieses Ticket: gelten pro Abteilung (Rolle des Mitarbeiters in der Abteilung des Tickets)
$summary['permissions'] = [];
foreach (['reply_ticket', 'post_note', 'close_ticket', 'assign_ticket', 'transfer_ticket', 'delete_ticket'] as $__perm) {
$summary['permissions'][$__perm] = has_permission($staff, $__perm, (int) $ticket['department_id']);
}
api_json(['ticket' => $summary]);