SUPPORT_MAX_FILE_SIZE) { continue; } // Validate extension $ext = strtolower(pathinfo($originalName, PATHINFO_EXTENSION)); if (!in_array($ext, SUPPORT_ALLOWED_EXTENSIONS)) { continue; } // Validate MIME type $finfo = new finfo(FILEINFO_MIME_TYPE); $detectedType = $finfo->file($tmpName); if (!in_array($detectedType, SUPPORT_ALLOWED_TYPES)) { continue; } // Generate unique filename $storedName = 'support_' . $messageId . '_' . uniqid() . '.' . $ext; $fullPath = $uploadPath . $storedName; $relativePath = SUPPORT_UPLOAD_URL . $monthDir . '/' . $storedName; if (move_uploaded_file($tmpName, $fullPath)) { try { $stmt = $pdo->prepare(" INSERT INTO support_attachments (message_id, file_name, original_name, file_path, file_type, file_size) VALUES (?, ?, ?, ?, ?, ?) "); $stmt->execute([$messageId, $storedName, $originalName, $relativePath, $detectedType, $fileSize]); $attachmentIds[] = $pdo->lastInsertId(); } catch (Exception $e) { // Clean up file if DB insert fails @unlink($fullPath); } } } return $attachmentIds; } /** * Get attachments for multiple messages (batch load) * @param PDO $pdo * @param array $messageIds Array of message IDs * @return array Keyed by message_id => [attachments] */ function getAttachmentsForMessages($pdo, $messageIds) { $result = []; if (empty($messageIds)) return $result; $placeholders = implode(',', array_fill(0, count($messageIds), '?')); $stmt = $pdo->prepare(" SELECT * FROM support_attachments WHERE message_id IN ($placeholders) ORDER BY created_at ASC "); $stmt->execute($messageIds); $attachments = $stmt->fetchAll(); foreach ($attachments as $att) { $result[$att['message_id']][] = $att; } return $result; } /** * Render attachment HTML for display * @param array $attachments Array of attachment rows * @return string HTML string */ function renderAttachmentsHTML($attachments) { if (empty($attachments)) return ''; $html = '
'; return $html; } /** * Get Font Awesome icon class for file type */ function getFileIcon($mimeType, $fileName) { $ext = strtolower(pathinfo($fileName, PATHINFO_EXTENSION)); $icons = [ 'pdf' => 'fa-file-pdf', 'doc' => 'fa-file-word', 'docx' => 'fa-file-word', 'xls' => 'fa-file-excel', 'xlsx' => 'fa-file-excel', 'csv' => 'fa-file-csv', 'txt' => 'fa-file-alt', ]; return $icons[$ext] ?? 'fa-file'; } /** * Format file size to human readable */ function formatFileSize($bytes) { if ($bytes >= 1048576) return round($bytes / 1048576, 1) . ' MB'; if ($bytes >= 1024) return round($bytes / 1024, 1) . ' KB'; return $bytes . ' B'; } /** * CSS for attachments (include once per page) */ function getAttachmentCSS() { return ' '; } /** * Generate file input HTML for forms * @param string $inputName Name attribute for file input (default: attachments) * @return string HTML for file upload section */ function getFileUploadHTML($inputName = 'attachments') { return '