getConnection(); } catch (Exception $e) { logPartnerActivity('Database connection failed: ' . $e->getMessage()); die('System error. Please try again later.'); } $success_message = ''; $error_message = ''; // Check if viewing a specific ticket $viewTicketId = isset($_GET['ticket']) ? intval($_GET['ticket']) : null; $viewTicket = null; $ticketMessages = []; $messageAttachments = []; // ── Handle ticket reply ── if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['reply_ticket_id'])) { $replyTicketId = intval($_POST['reply_ticket_id']); $replyMessage = isset($_POST['reply_message']) ? trim($_POST['reply_message']) : ''; if (empty($replyMessage)) { $error_message = 'Reply message cannot be empty.'; } elseif (strlen($replyMessage) > 5000) { $error_message = 'Reply must be 5000 characters or less.'; } else { try { $stmt = $pdo->prepare("SELECT id, status FROM support_tickets WHERE id = ? AND sender_type = 'partner' AND sender_id = ?"); $stmt->execute([$replyTicketId, $partner['id']]); $ticket = $stmt->fetch(); if (!$ticket) { $error_message = 'Ticket not found or access denied.'; } elseif ($ticket['status'] === 'closed') { $error_message = 'Cannot reply to a closed ticket.'; } else { $stmt = $pdo->prepare("INSERT INTO support_messages (ticket_id, sender_type, sender_id, message, is_internal) VALUES (?, 'user', ?, ?, 0)"); $stmt->execute([$replyTicketId, $partner['id'], $replyMessage]); $messageId = $pdo->lastInsertId(); // Handle file attachments if ($supportHelperLoaded && !empty($_FILES['attachments']['name'][0])) { handleSupportAttachments($pdo, $messageId, $_FILES['attachments']); } // Reopen ticket if resolved/pending if (in_array($ticket['status'], ['resolved', 'pending'])) { $pdo->prepare("UPDATE support_tickets SET status = 'open', updated_at = NOW() WHERE id = ?")->execute([$replyTicketId]); } else { $pdo->prepare("UPDATE support_tickets SET updated_at = NOW() WHERE id = ?")->execute([$replyTicketId]); } $success_message = 'Reply sent successfully!'; $viewTicketId = $replyTicketId; logPartnerActivity('Partner replied to ticket', ['ticket_id' => $replyTicketId]); } } catch (Exception $e) { $error_message = 'Failed to send reply. Please try again.'; logPartnerActivity('Error replying to ticket: ' . $e->getMessage()); } } } // ── Handle ticket creation ── if ($_SERVER['REQUEST_METHOD'] === 'POST' && !isset($_POST['reply_ticket_id'])) { $subject = isset($_POST['subject']) ? trim($_POST['subject']) : ''; $message = isset($_POST['message']) ? trim($_POST['message']) : ''; $priority = isset($_POST['priority']) ? $_POST['priority'] : 'medium'; if (empty($subject) || empty($message)) { $error_message = 'Subject and message are required.'; } elseif (strlen($subject) > 255) { $error_message = 'Subject must be 255 characters or less.'; } elseif (strlen($message) > 5000) { $error_message = 'Message must be 5000 characters or less.'; } else { try { $pdo->beginTransaction(); $ticketNumber = 'TKT-' . date('Ymd') . '-' . strtoupper(substr(bin2hex(random_bytes(4)), 0, 6)); // user_id NULL for partner tickets (FK references users table) $stmt = $pdo->prepare("INSERT INTO support_tickets (ticket_number, user_id, sender_type, sender_id, subject, status, priority) VALUES (?, NULL, 'partner', ?, ?, 'open', ?)"); $stmt->execute([$ticketNumber, $partner['id'], $subject, $priority]); $ticketId = $pdo->lastInsertId(); $stmt = $pdo->prepare("INSERT INTO support_messages (ticket_id, sender_type, sender_id, message, is_internal) VALUES (?, 'user', ?, ?, 0)"); $stmt->execute([$ticketId, $partner['id'], $message]); $messageId = $pdo->lastInsertId(); $pdo->commit(); // Handle file attachments if ($supportHelperLoaded && !empty($_FILES['attachments']['name'][0])) { handleSupportAttachments($pdo, $messageId, $_FILES['attachments']); } $success_message = "Support ticket created successfully! Ticket Number: $ticketNumber
We will respond to your query shortly."; logPartnerActivity('Support ticket created', ['ticket_number' => $ticketNumber, 'partner_id' => $partner['id'], 'subject' => $subject]); $_POST = []; } catch (Exception $e) { if ($pdo->inTransaction()) $pdo->rollBack(); logPartnerActivity('Error creating support ticket: ' . $e->getMessage()); $error_message = 'Failed to create support ticket. Please try again.'; } } } // ── Load ticket detail if viewing ── if ($viewTicketId) { try { $stmt = $pdo->prepare("SELECT st.*, au.full_name as assigned_to_name FROM support_tickets st LEFT JOIN admin_users au ON st.assigned_to = au.id WHERE st.id = ? AND st.sender_type = 'partner' AND st.sender_id = ?"); $stmt->execute([$viewTicketId, $partner['id']]); $viewTicket = $stmt->fetch(); if ($viewTicket) { $stmt = $pdo->prepare("SELECT sm.*, CASE WHEN sm.sender_type = 'admin' THEN COALESCE((SELECT full_name FROM admin_users WHERE id = sm.sender_id), 'Support Team') ELSE ? END as sender_name FROM support_messages sm WHERE sm.ticket_id = ? AND sm.is_internal = 0 ORDER BY sm.created_at ASC"); $stmt->execute([$partner['company_name'], $viewTicketId]); $ticketMessages = $stmt->fetchAll(); // Load attachments for all messages if ($supportHelperLoaded && function_exists('getAttachmentsForMessages') && !empty($ticketMessages)) { $msgIds = array_column($ticketMessages, 'id'); $messageAttachments = getAttachmentsForMessages($pdo, $msgIds); } } } catch (Exception $e) { logPartnerActivity('Error loading ticket: ' . $e->getMessage()); } } // ── Load tickets list ── try { $stmt = $pdo->prepare("SELECT st.*, au.full_name as assigned_to_name, (SELECT COUNT(*) FROM support_messages WHERE ticket_id = st.id AND is_internal = 0) as message_count FROM support_tickets st LEFT JOIN admin_users au ON st.assigned_to = au.id WHERE st.sender_type = 'partner' AND st.sender_id = ? ORDER BY st.created_at DESC"); $stmt->execute([$partner['id']]); $tickets = $stmt->fetchAll(); } catch (Exception $e) { logPartnerActivity('Error fetching tickets: ' . $e->getMessage()); $tickets = []; } // Helper: get file icon class function getPartnerFileIcon($type, $name) { $ext = strtolower(pathinfo($name, PATHINFO_EXTENSION)); if (in_array($ext, ['jpg','jpeg','png','gif','webp'])) return 'fa-file-image'; if ($ext === 'pdf') return 'fa-file-pdf'; if (in_array($ext, ['doc','docx'])) return 'fa-file-word'; if (in_array($ext, ['xls','xlsx','csv'])) return 'fa-file-excel'; return 'fa-file-alt'; } ?> <?php echo $viewTicket ? 'Ticket #'.htmlspecialchars($viewTicket['ticket_number']) : 'Partner Support'; ?> - Relevant Reflex
RELEVANT REFLEXPARTNERS

Conversation

No messages yet.

' : ' '; ?>
'; foreach ($messageAttachments[$msg['id']] as $att) { $icon = getPartnerFileIcon($att['file_type'], $att['original_name']); $sizeMB = number_format(($att['file_size'] ?? 0) / 1024 / 1024, 1); echo ' ' . htmlspecialchars($att['original_name']) . ' (' . $sizeMB . ' MB)'; } echo '
'; } ?>
Send Reply
Max 3 files, 5MB each.
This ticket is closed. If you need further help, please create a new ticket.

Create New Support Ticket

Maximum 5000 characters
Max 3 files, 5MB each. Accepted: Images, PDF, Word, Excel, Text.

Your Support Tickets ()

No tickets yet

You haven't created any support tickets. Create one above if you need assistance.