<?php
// Включение отображения ошибок для отладки (убрать на продакшене)
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);
error_reporting(E_ALL);
// Проверка, была ли сессия уже запущена
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
require_once 'config.php';
require_once 'includes/db.php';
require_once 'includes/auth.php';
// Проверка авторизации
require_login(); // Убедимся, что пользователь авторизован
global $pdo;
$user_id = $_SESSION['user_id'];
// Генерация CSRF-токена
$csrf_token = generate_csrf_token(); // Используем функцию из includes/auth.php
// Получаем список диалогов (последние сообщения от каждого пользователя) с проверкой непрочитанных
$stmt = $pdo->prepare("SELECT DISTINCT
CASE
WHEN m.sender_id = ? THEN m.receiver_id
ELSE m.sender_id
END as other_user_id,
u.login,
u.avatar,
MAX(m.created_at) as last_message_time,
m.message as message,
(SELECT COUNT(*) FROM messages m2 WHERE m2.receiver_id = ? AND m2.sender_id = CASE
WHEN m.sender_id = ? THEN m.receiver_id
ELSE m.sender_id
END AND m2.is_read = FALSE) as unread_count
FROM messages m
JOIN users u ON u.id = CASE
WHEN m.sender_id = ? THEN m.receiver_id
ELSE m.sender_id
END
WHERE m.receiver_id = ? OR m.sender_id = ?
GROUP BY other_user_id, u.login, u.avatar
ORDER BY last_message_time DESC");
$stmt->execute([$user_id, $user_id, $user_id, $user_id, $user_id, $user_id]);
$dialogues = $stmt->fetchAll();
// Обработка удаления диалога (все сообщения с конкретным пользователем)
if ($_SERVER['REQUEST_METHOD'] === 'POST' && isset($_POST['delete_dialogue_id'])) {
// Проверка CSRF-токена
if (!verify_csrf_token()) {
$error = "Недействительный запрос. Попробуйте снова.";
} else {
$other_user_id = (int)$_POST['delete_dialogue_id'];
try {
$stmt = $pdo->prepare("DELETE FROM messages WHERE (sender_id = ? AND receiver_id = ?) OR (sender_id = ? AND receiver_id = ?)");
$stmt->execute([$user_id, $other_user_id, $other_user_id, $user_id]);
header('Location: messages.php');
exit;
} catch (PDOException $e) {
error_log("Ошибка удаления диалога: " . $e->getMessage());
$error = "Произошла ошибка при удалении диалога. Обратитесь к администратору.";
}
}
}
?>
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<link rel="stylesheet" href="assets/css/style.css">
<title>Сообщения — AstralForge</title>
<style>
/* Стили для аватаров */
.user-avatar, .default-avatar {
width: 25px;
height: 25px;
object-fit: cover;
border-radius: 50%;
border: 2px solid #fff;
box-shadow: 0 2px 4px rgba(0, 0, 0, 0.08);
}
.user-avatar:hover, .default-avatar:hover {
transform: scale(1.1);
}
.default-avatar {
background: linear-gradient(45deg, #ecf0f1, #bdc3c7);
display: flex;
align-items: center;
justify-content: center;
font-size: 14px;
color: #666;
}
/* Стили для карточек диалогов */
.message-card {
background: linear-gradient(135deg, #f9f9f9, #f5f7fa);
padding: 12px;
border-radius: 10px;
box-shadow: 0 3px 10px rgba(0, 0, 0, 0.08);
margin-bottom: 12px;
}
.message-card:hover {
transform: translateY(-4px);
}
/* Стили для действий в карточках */
.message-actions {
display: flex;
align-items: center;
justify-content: space-between;
}
/* Стили для ссылок диалогов */
.message-link {
display: flex;
align-items: center;
gap: 12px;
text-decoration: none;
color: #333;
flex-grow: 1;
}
.message-link:hover {
opacity: 0.8;
}
/* Стили для информации о диалоге */
.message-info {
flex-grow: 1;
}
/* Стили для имени пользователя */
.message-username {
font-weight: 600;
margin: 0 0 6px 0;
color: #2c3e50;
font-size: 0.9em;
}
.message-username:hover {
color: #3498db;
}
/* Стили для предпросмотра сообщения */
.message-preview {
margin: 0;
color: #666;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
font-size: 0.8em;
}
.message-preview:hover {
color: #555;
}
/* Стили для времени сообщения */
.message-time {
font-size: 11px;
color: #999;
margin-top: 4px;
}
.message-time:hover {
color: #777;
}
/* Стили для оповещения "Новое" */
.message-unread {
background: linear-gradient(135deg, #e74c3c, #c0392b);
color: #fff;
padding: 3px 8px;
border-radius: 10px;
font-size: 9px;
margin-left: 8px;
box-shadow: 0 2px 4px rgba(231, 76, 60, 0.25);
}
.message-unread:hover {
transform: scale(1.1);
}
/* Стили для кнопки удаления */
.message-delete {
color: #e74c3c;
text-decoration: none;
font-size: 11px;
padding: 5px 10px;
border: 2px solid #e74c3c;
border-radius: 8px;
}
.message-delete:hover {
background: #e74c3c;
color: #fff;
transform: translateY(-2px);
}
</style>
</head>
<body>
<nav class="navbar">
<div class="navbar-container">
<?php if (isset($_SESSION['user_id'])): ?>
<div class="navbar-user">
<a href="profile.php" class="navbar-avatar-link">
<?php
$current_user = $pdo->prepare("SELECT avatar, login FROM users WHERE id = ?");
$current_user->execute([$_SESSION['user_id']]);
$current_user_data = $current_user->fetch();
?>
<?php if (empty($current_user_data['avatar'])): ?>
<span class="default-avatar navbar-avatar">?</span>
<?php else: ?>
<img src="<?php echo htmlspecialchars($current_user_data['avatar']); ?>" alt="Ваш аватар" class="navbar-avatar" onerror="this.replaceWith(document.createElement('span').classList.add('default-avatar', 'navbar-avatar').textContent='?');">
<?php endif; ?>
</a>
<a href="profile.php" class="navbar-username"><?php echo htmlspecialchars($current_user_data['login']); ?></a>
</div>
<div class="navbar-links">
<a href="index.php">Главная</a>
<a href="user_list.php">Пользователи</a>
<a href="messages.php">
<span class="message-icon"></span>
</a>
<?php if (isset($_SESSION['is_admin']) && $_SESSION['is_admin']) echo '<a href="admin/index.php">Админ-панель</a>'; ?>
<a href="logout.php">Выход</a>
</div>
<?php endif; ?>
</div>
</nav>
<div class="container">
<h1>Сообщения</h1>
<?php if (isset($error)): ?>
<p style="color: #e74c3c;"><?php echo htmlspecialchars($error); ?></p>
<?php endif; ?>
<div class="messages-list">
<?php if (count($dialogues) > 0): ?>
<?php foreach ($dialogues as $dialogue): ?>
<div class="message-card">
<div class="message-actions">
<a href="chat.php?user_id=<?php echo htmlspecialchars($dialogue['other_user_id']); ?>" class="message-link">
<?php if (empty($dialogue['avatar'])): ?>
<span class="default-avatar">?</span>
<?php else: ?>
<img src="<?php echo htmlspecialchars($dialogue['avatar']); ?>" alt="<?php echo htmlspecialchars($dialogue['login']); ?>" class="user-avatar" onerror="this.replaceWith(document.createElement('span').classList.add('default-avatar').textContent='?');">
<?php endif; ?>
<div class="message-info">
<p class="message-username"><?php echo htmlspecialchars($dialogue['login']); ?></p>
<p class="message-preview"><?php echo htmlspecialchars($dialogue['message'] ?: 'Сообщение отсутствует'); ?></p>
<p class="message-time"><?php echo htmlspecialchars(date('H:i d.m.Y', strtotime($dialogue['last_message_time']))); ?>
<?php if ($dialogue['unread_count'] > 0): ?>
<span class="message-unread">Новое</span>
<?php endif; ?>
</p>
</div>
</a>
<a href="#" class="message-delete" onclick="if(confirm('Удалить диалог?')){document.getElementById('delete-form-<?php echo $dialogue['other_user_id']; ?>').submit();} return false;">Удалить</a>
<form id="delete-form-<?php echo $dialogue['other_user_id']; ?>" method="POST" action="messages.php" style="display: none;">
<input type="hidden" name="delete_dialogue_id" value="<?php echo htmlspecialchars($dialogue['other_user_id']); ?>">
<input type="hidden" name="csrf_token" value="<?php echo htmlspecialchars($csrf_token); ?>">
</form>
</div>
</div>
<?php endforeach; ?>
<?php else: ?>
<p class="no-results">Диалоги не найдены.</p>
<?php endif; ?>
</div>
</div>
</body>
</html>