'[ + ]', 'update' => '[ ~ ]', 'comment' => '[ > ]', 'view' => '[ . ]', 'assign' => '[ @ ]', 'status_change' => '[ ! ]', default => '[ * ]', }; } function formatAction(array $event): string { return match($event['action_type']) { 'create' => 'created this ticket', 'update' => 'updated this ticket', 'comment' => 'added a comment', 'view' => 'viewed this ticket', 'assign' => 'assigned this ticket', 'status_change' => 'changed the status', default => $event['action_type'], }; } // Calculate ticket age $lastUpdate = !empty($ticket['updated_at']) ? strtotime($ticket['updated_at']) : strtotime($ticket['created_at']); $ageSeconds = time() - $lastUpdate; $ageDays = floor($ageSeconds / 86400); $ageHours = floor(($ageSeconds % 86400) / 3600); $ageClass = 'lt-text-muted'; if ($ticket['status'] !== 'Closed') { if ($ageDays >= 10) $ageClass = 'lt-text-danger'; elseif ($ageDays >= 5) $ageClass = 'lt-text-amber'; } $ageStr = $ageDays > 0 ? $ageDays . ' day' . ($ageDays !== 1 ? 's' : '') : $ageHours . ' hour' . ($ageHours !== 1 ? 's' : ''); $statusSlug = strtolower(str_replace(' ', '-', $ticket['status'])); $priorityNum = (int)($ticket['priority'] ?? 3); $currentUserId = $GLOBALS['currentUser']['user_id'] ?? null; $isAdmin = $GLOBALS['currentUser']['is_admin'] ?? false; $creator = $ticket['creator_display_name'] ?? $ticket['creator_username'] ?? 'System'; // Visibility $currentVisibility = $ticket['visibility'] ?? 'public'; $currentVisibilityGroups = array_filter(array_map('trim', explode(',', $ticket['visibility_groups'] ?? ''))); require_once __DIR__ . '/../models/UserModel.php'; $visUserModel = new UserModel($conn); $allAvailableGroups = $visUserModel->getAllGroups(); // JSON-encode ticket fields for the inline script $json_ticket_id = json_encode($ticket['ticket_id'], JSON_HEX_TAG); $json_title = json_encode($ticket['title'], JSON_HEX_TAG); $json_status = json_encode($ticket['status'], JSON_HEX_TAG); $json_priority = json_encode($ticket['priority'], JSON_HEX_TAG); $json_category = json_encode($ticket['category'], JSON_HEX_TAG); $json_type = json_encode($ticket['type'], JSON_HEX_TAG); $json_updated_at = json_encode($ticket['updated_at'], JSON_HEX_TAG); $json_total_comments = json_encode((int)$totalComments, JSON_HEX_TAG); $json_comment_page = json_encode((int)$commentPageSize, JSON_HEX_TAG); $json_current_uid = json_encode((int)($currentUser['user_id'] ?? 0), JSON_HEX_TAG); $json_is_admin = json_encode(!empty($currentUser['is_admin']), JSON_HEX_TAG); $pageInlineScript = <<
← Dashboard / Ticket #
EXPORT
Ticket Information

UUID
Priority
Category
Type
Assigned To
Visibility
Age ago
Created By
Last Updated
No groups available
Description
Add Comment
Comment History
No comments yet. Be the first to comment.
(edited)' : ''; // Avatar initials + color (fallback when no photo) $words = array_filter(explode(' ', $displayName)); $initials = strtoupper(implode('', array_map(fn($w) => $w[0], array_slice($words, 0, 2)))); $avatarColors = ['lt-avatar--orange', 'lt-avatar--green', 'lt-avatar--purple', '']; $avatarColor = $avatarColors[abs(crc32($displayName)) % count($avatarColors)]; $commentUserId = (int)($comment['user_id'] ?? 0); ?>
>
$commentPageSize): ?>
Upload Files

Drag & drop files here or click to browse

Max size:

Attached Files

Loading attachments…

Add Dependency
Current Dependencies

Loading…

Tickets That Depend On This

Loading…

Activity Timeline
No activity recorded yet.
'lt-timeline-item--green', 'status_change' => 'lt-timeline-item--orange', 'comment' => '', default => 'lt-timeline-item--dim', }; ?>
$v) { // Delta format: { field: { from: '...', to: '...' } } if (is_array($v) && isset($v['from'], $v['to'])) { $label = ucfirst(str_replace('_', ' ', $k)); // Truncate long values (e.g. description) $from = mb_strlen((string)$v['from']) > 60 ? mb_substr((string)$v['from'], 0, 60) . '…' : (string)$v['from']; $to = mb_strlen((string)$v['to']) > 60 ? mb_substr((string)$v['to'], 0, 60) . '…' : (string)$v['to']; $parts[] = '' . htmlspecialchars($label) . ': ' . '' . htmlspecialchars($from) . '' . ' ' . '' . htmlspecialchars($to) . ''; } elseif ($k !== 'old_value' && $k !== 'new_value') { // Legacy flat format fallback $parts[] = '' . htmlspecialchars($k) . ': ' . htmlspecialchars((string)$v); } } echo implode('
', $parts); } ?>