208 lines
6.5 KiB
PHP
208 lines
6.5 KiB
PHP
<?php
|
|
session_start();
|
|
|
|
if (!isset($_SESSION['user_id'])) {
|
|
http_response_code(401);
|
|
echo json_encode(['error' => 'User not authenticated']);
|
|
exit;
|
|
}
|
|
|
|
require_once 'db/config.php';
|
|
|
|
header('Content-Type: application/json');
|
|
|
|
$action = isset($_POST['action']) ? $_POST['action'] : ($_GET['action'] ?? '');
|
|
$current_user_id = $_SESSION['user_id'];
|
|
|
|
try {
|
|
switch ($action) {
|
|
case 'get_new_messages':
|
|
getNewMessages();
|
|
break;
|
|
case 'send_message':
|
|
sendMessage();
|
|
break;
|
|
case 'create_room':
|
|
createRoom();
|
|
break;
|
|
case 'start_private_chat':
|
|
startPrivateChat();
|
|
break;
|
|
default:
|
|
throw new Exception("Invalid action.");
|
|
}
|
|
} catch (Exception $e) {
|
|
http_response_code(400);
|
|
echo json_encode(['success' => false, 'error' => $e->getMessage()]);
|
|
}
|
|
|
|
function sendMessage() {
|
|
global $current_user_id;
|
|
|
|
$message = trim($_POST['message'] ?? '');
|
|
$room_id = $_POST['room_id'] ?? null;
|
|
|
|
if (empty($message) && empty($_FILES['attachment']['name'])) {
|
|
throw new Exception("Message or attachment cannot be empty.");
|
|
}
|
|
if (!$room_id) {
|
|
throw new Exception("Invalid room.");
|
|
}
|
|
|
|
$pdo = db();
|
|
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
|
|
|
|
$has_attachment = false;
|
|
$file_data = null;
|
|
|
|
// Handle file upload
|
|
if (isset($_FILES['attachment']) && $_FILES['attachment']['error'] == UPLOAD_ERR_OK) {
|
|
$file = $_FILES['attachment'];
|
|
if ($file['size'] > 100 * 1024 * 1024) { // 100MB limit
|
|
throw new Exception("File size exceeds the 100MB limit.");
|
|
}
|
|
|
|
$upload_dir = 'uploads/';
|
|
if (!is_dir($upload_dir)) {
|
|
mkdir($upload_dir, 0775, true);
|
|
}
|
|
$file_name = uniqid() . '-' . basename($file['name']);
|
|
$file_path = $upload_dir . $file_name;
|
|
|
|
if (move_uploaded_file($file['tmp_name'], $file_path)) {
|
|
$has_attachment = true;
|
|
$file_data = [
|
|
'name' => $file['name'],
|
|
'path' => $file_path,
|
|
'size' => $file['size'],
|
|
'type' => $file['type']
|
|
];
|
|
} else {
|
|
throw new Exception("Failed to upload file.");
|
|
}
|
|
}
|
|
|
|
$pdo->beginTransaction();
|
|
|
|
$stmt = $pdo->prepare("INSERT INTO messages (user_id, room_id, message) VALUES (?, ?, ?)");
|
|
$stmt->execute([$current_user_id, $room_id, $message]);
|
|
$message_id = $pdo->lastInsertId();
|
|
|
|
if ($has_attachment && $file_data) {
|
|
$stmt = $pdo->prepare("INSERT INTO files (message_id, original_name, file_path, file_size, mime_type) VALUES (?, ?, ?, ?, ?)");
|
|
$stmt->execute([$message_id, $file_data['name'], $file_data['path'], $file_data['size'], $file_data['type']]);
|
|
}
|
|
|
|
$pdo->commit();
|
|
echo json_encode(['success' => true]);
|
|
}
|
|
|
|
|
|
function getNewMessages() {
|
|
global $current_user_id;
|
|
$roomId = $_GET['room_id'] ?? 0;
|
|
$lastMessageId = $_GET['last_message_id'] ?? 0;
|
|
|
|
if (empty($roomId)) {
|
|
echo json_encode([]);
|
|
exit;
|
|
}
|
|
|
|
$pdo = db();
|
|
|
|
// Check if user is a member of the room
|
|
$stmt = $pdo->prepare("SELECT 1 FROM room_members WHERE room_id = ? AND user_id = ?");
|
|
$stmt->execute([$roomId, $current_user_id]);
|
|
if ($stmt->fetchColumn() === false) {
|
|
// If not a member, check if it's a public room (no members defined)
|
|
$stmt = $pdo->prepare("SELECT COUNT(*) FROM room_members WHERE room_id = ?");
|
|
$stmt->execute([$roomId]);
|
|
if ($stmt->fetchColumn() > 0) {
|
|
http_response_code(403);
|
|
throw new Exception("Access denied to room");
|
|
}
|
|
}
|
|
|
|
// Poll for new messages
|
|
$startTime = time();
|
|
$timeout = 25; // 25 seconds timeout for long polling
|
|
|
|
while (time() - $startTime < $timeout) {
|
|
$stmt = $pdo->prepare("
|
|
SELECT
|
|
m.id, m.message, m.created_at, u.username,
|
|
f.original_name as file_name, f.file_path, f.file_size, f.mime_type as file_type
|
|
FROM messages m
|
|
JOIN users u ON m.user_id = u.id
|
|
LEFT JOIN files f ON m.id = f.message_id
|
|
WHERE m.room_id = ? AND m.id > ?
|
|
ORDER BY m.id ASC
|
|
");
|
|
$stmt->execute([$roomId, $lastMessageId]);
|
|
$messages = $stmt->fetchAll(PDO::FETCH_ASSOC);
|
|
|
|
if (!empty($messages)) {
|
|
echo json_encode($messages);
|
|
exit;
|
|
}
|
|
|
|
// Wait for a short period before polling again
|
|
sleep(1);
|
|
}
|
|
|
|
// If no new messages after timeout, return empty array
|
|
echo json_encode([]);
|
|
}
|
|
|
|
function createRoom() {
|
|
global $current_user_id;
|
|
$room_name = trim($_POST['room_name'] ?? '');
|
|
if (empty($room_name)) {
|
|
throw new Exception("Room name cannot be empty.");
|
|
}
|
|
$pdo = db();
|
|
$stmt = $pdo->prepare("INSERT INTO rooms (name, created_by) VALUES (?, ?)");
|
|
$stmt->execute([$room_name, $current_user_id]);
|
|
$new_room_id = $pdo->lastInsertId();
|
|
|
|
$stmt = $pdo->prepare("INSERT INTO room_members (room_id, user_id) VALUES (?, ?)");
|
|
$stmt->execute([$new_room_id, $current_user_id]);
|
|
|
|
echo json_encode(['success' => true, 'room_id' => $new_room_id]);
|
|
}
|
|
|
|
function startPrivateChat() {
|
|
global $current_user_id;
|
|
$other_user_id = $_POST['user_id'] ?? null;
|
|
if (!$other_user_id || $other_user_id == $current_user_id) {
|
|
throw new Exception("Invalid user ID.");
|
|
}
|
|
|
|
$pdo = db();
|
|
// Check if a private room already exists between the two users
|
|
$stmt = $pdo->prepare("
|
|
SELECT r.id FROM rooms r
|
|
JOIN room_members rm1 ON r.id = rm1.room_id
|
|
JOIN room_members rm2 ON r.id = rm2.room_id
|
|
WHERE r.is_private = 1
|
|
AND rm1.user_id = ?
|
|
AND rm2.user_id = ?
|
|
");
|
|
$stmt->execute([$current_user_id, $other_user_id]);
|
|
$room = $stmt->fetch();
|
|
|
|
if ($room) {
|
|
echo json_encode(['success' => true, 'room_id' => $room['id']]);
|
|
} else {
|
|
// Create a new private room
|
|
$stmt = $pdo->prepare("INSERT INTO rooms (name, created_by, is_private) VALUES (?, ?, 1)");
|
|
$stmt->execute(["Private Chat", $current_user_id]);
|
|
$new_room_id = $pdo->lastInsertId();
|
|
|
|
// Add both users to the new room
|
|
$stmt = $pdo->prepare("INSERT INTO room_members (room_id, user_id) VALUES (?, ?), (?, ?)");
|
|
$stmt->execute([$new_room_id, $current_user_id, $new_room_id, $other_user_id]);
|
|
|
|
echo json_encode(['success' => true, 'room_id' => $new_room_id]);
|
|
}
|
|
} |