Tul xxx Tul
User / IP
:
216.73.216.217
Host / Server
:
45.84.207.204 / aircan.me
System
:
Linux lt-bnk-web1726.main-hosting.eu 5.14.0-611.36.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Mar 3 11:23:52 EST 2026 x86_64
Command
|
Upload
|
Create
Mass Deface
|
Jumping
|
Symlink
|
Reverse Shell
Ping
|
Port Scan
|
DNS Lookup
|
Whois
|
Header
|
cURL
:
/
home
/
u931257429
/
domains
/
aircan.me
/
public_html
/
tours
/
app
/
models
/
Viewing: Chat.php
<?php declare(strict_types=1); class Chat extends Model { // ─── Conversations ─── /** * Busca o crea la conversación de un usuario. */ public function findOrCreateConversation(int $userId): ?array { if (!$this->db instanceof PDO) return null; $stmt = $this->db->prepare('SELECT * FROM conversations WHERE user_id = :uid LIMIT 1'); $stmt->execute(['uid' => $userId]); $conv = $stmt->fetch(); if ($conv) return $conv; $stmt = $this->db->prepare( 'INSERT INTO conversations (user_id, created_at) VALUES (:uid, NOW())' ); $stmt->execute(['uid' => $userId]); $newId = (int) $this->db->lastInsertId(); return $this->findConversationById($newId); } /** * Obtiene una conversación por ID. */ public function findConversationById(int $id): ?array { if (!$this->db instanceof PDO) return null; $stmt = $this->db->prepare('SELECT * FROM conversations WHERE id = :id LIMIT 1'); $stmt->execute(['id' => $id]); $row = $stmt->fetch(); return $row ?: null; } /** * Lista conversaciones con datos del usuario y último mensaje. * Para admin/client: todas. Para user: solo la suya. */ public function getConversations(?int $userId = null): array { if (!$this->db instanceof PDO) return []; $sql = "SELECT c.id, c.user_id, c.assigned_to, c.last_message_at, c.created_at, u.name AS user_name, u.email AS user_email, u.photo AS user_photo, (SELECT m.message FROM messages m WHERE m.conversation_id = c.id ORDER BY m.id DESC LIMIT 1) AS last_message, (SELECT m.sender_id FROM messages m WHERE m.conversation_id = c.id ORDER BY m.id DESC LIMIT 1) AS last_sender_id, (SELECT COUNT(*) FROM messages m WHERE m.conversation_id = c.id AND m.is_read = 0 AND m.sender_id = c.user_id) AS unread_count FROM conversations c INNER JOIN users u ON u.id = c.user_id"; $params = []; if ($userId !== null) { $sql .= ' WHERE c.user_id = :uid'; $params['uid'] = $userId; } $sql .= ' ORDER BY c.last_message_at DESC, c.created_at DESC'; $stmt = $this->db->prepare($sql); $stmt->execute($params); return $stmt->fetchAll() ?: []; } /** * Cuenta no leídos para un usuario (mensajes enviados POR el user, no leídos por admin). * Para admin: cuenta mensajes no leídos de todos los users. * Para user: cuenta mensajes no leídos enviados por admin/client. */ public function getUnreadCount(int $currentUserId, string $role): int { if (!$this->db instanceof PDO) return 0; if (in_array($role, ['admin', 'client'], true)) { // Admin ve mensajes no leídos que enviaron los users $stmt = $this->db->query( "SELECT COUNT(*) AS cnt FROM messages m INNER JOIN conversations c ON c.id = m.conversation_id WHERE m.is_read = 0 AND m.sender_id = c.user_id" ); } else { // User ve mensajes no leídos que le enviaron (sender_id != user_id) $stmt = $this->db->prepare( "SELECT COUNT(*) AS cnt FROM messages m INNER JOIN conversations c ON c.id = m.conversation_id WHERE m.is_read = 0 AND c.user_id = :uid AND m.sender_id != :uid2" ); $stmt->execute(['uid' => $currentUserId, 'uid2' => $currentUserId]); } $row = $stmt->fetch(); return (int) ($row['cnt'] ?? 0); } /** * Directorio de todos los clientes/usuarios disponibles para iniciar chat. */ public function getDirectory(int $currentUserId): array { if (!$this->db instanceof PDO) return []; $stmt = $this->db->prepare( "SELECT id, name, email, role, photo, status, created_at FROM users WHERE id != :uid AND role IN ('client', 'user') AND status = 'active' ORDER BY name ASC" ); $stmt->execute(['uid' => $currentUserId]); return $stmt->fetchAll() ?: []; } /** * Actualiza el timestamp del último mensaje de una conversación. */ public function touchConversation(int $conversationId): void { if (!$this->db instanceof PDO) return; $stmt = $this->db->prepare('UPDATE conversations SET last_message_at = NOW() WHERE id = :id'); $stmt->execute(['id' => $conversationId]); } // ─── Messages ─── /** * Obtiene todos los mensajes de una conversación con datos del sender. */ public function getMessages(int $conversationId): array { if (!$this->db instanceof PDO) return []; $stmt = $this->db->prepare( "SELECT m.id, m.conversation_id, m.sender_id, m.message, m.is_read, m.created_at, u.name AS sender_name, u.role AS sender_role, u.photo AS sender_photo FROM messages m INNER JOIN users u ON u.id = m.sender_id WHERE m.conversation_id = :cid ORDER BY m.created_at ASC, m.id ASC" ); $stmt->execute(['cid' => $conversationId]); return $stmt->fetchAll() ?: []; } /** * Envía un mensaje. */ public function sendMessage(int $conversationId, int $senderId, string $message): bool { if (!$this->db instanceof PDO) return false; $stmt = $this->db->prepare( 'INSERT INTO messages (conversation_id, sender_id, message, is_read, created_at) VALUES (:cid, :sid, :msg, 0, NOW())' ); $ok = $stmt->execute([ 'cid' => $conversationId, 'sid' => $senderId, 'msg' => $message, ]); if ($ok) { $this->touchConversation($conversationId); } return $ok; } /** * Marca como leídos los mensajes de una conversación que NO fueron enviados por currentUser. */ public function markAsRead(int $conversationId, int $currentUserId): bool { if (!$this->db instanceof PDO) return false; $stmt = $this->db->prepare( 'UPDATE messages SET is_read = 1 WHERE conversation_id = :cid AND sender_id != :uid AND is_read = 0' ); return $stmt->execute(['cid' => $conversationId, 'uid' => $currentUserId]); } }
Coded With 💗 by
0x6ick