194 lines
7.3 KiB
PHP
194 lines
7.3 KiB
PHP
<?php
|
|
/**
|
|
* API - Eliminar mensaje
|
|
* Permite eliminar un mensaje de la conversación
|
|
* Fecha: 28 de enero de 2026
|
|
*/
|
|
|
|
// Habilitar display de errores para debug
|
|
ini_set('display_errors', 1);
|
|
error_reporting(E_ALL);
|
|
|
|
require_once '../config/config.php';
|
|
|
|
// Log para debug
|
|
error_log("delete_message.php: Iniciando, session_id=" . session_id() . ", admin_logged_in=" . (isset($_SESSION['admin_logged_in']) ? $_SESSION['admin_logged_in'] : 'no definido'));
|
|
|
|
requireAuthentication();
|
|
|
|
header('Content-Type: application/json; charset=utf-8');
|
|
header('Access-Control-Allow-Origin: *');
|
|
header('Access-Control-Allow-Methods: POST, DELETE, OPTIONS');
|
|
header('Access-Control-Allow-Headers: Content-Type');
|
|
|
|
// Manejar preflight OPTIONS request
|
|
if ($_SERVER['REQUEST_METHOD'] === 'OPTIONS') {
|
|
http_response_code(200);
|
|
exit;
|
|
}
|
|
|
|
if ($_SERVER['REQUEST_METHOD'] !== 'POST' && $_SERVER['REQUEST_METHOD'] !== 'DELETE') {
|
|
http_response_code(405);
|
|
echo json_encode(['success' => false, 'error' => 'Método no permitido. Use POST o DELETE.']);
|
|
exit;
|
|
}
|
|
|
|
try {
|
|
$input = json_decode(file_get_contents('php://input'), true);
|
|
|
|
// También soportar query params para DELETE
|
|
if (!$input && $_SERVER['REQUEST_METHOD'] === 'DELETE') {
|
|
$input = [
|
|
'message_id' => $_GET['message_id'] ?? $_GET['id'] ?? null,
|
|
'delete_for_everyone' => $_GET['delete_for_everyone'] ?? false
|
|
];
|
|
}
|
|
|
|
if (!$input) {
|
|
http_response_code(400);
|
|
echo json_encode(['success' => false, 'error' => 'JSON inválido']);
|
|
exit;
|
|
}
|
|
|
|
$messageId = $input['message_id'] ?? $input['id'] ?? null;
|
|
$deleteForEveryone = $input['delete_for_everyone'] ?? false;
|
|
$softDelete = $input['soft_delete'] ?? true; // Por defecto, soft delete
|
|
|
|
if (!$messageId) {
|
|
http_response_code(400);
|
|
echo json_encode(['success' => false, 'error' => 'message_id es requerido']);
|
|
exit;
|
|
}
|
|
|
|
$db = Database::getInstance();
|
|
|
|
// Buscar el mensaje
|
|
$sql = "SELECT id, user_id, direction, message_type, content, message_id as wa_message_id,
|
|
local_file, local_thumb, media_url
|
|
FROM conversations
|
|
WHERE id = :mid1 OR message_id = :mid2
|
|
LIMIT 1";
|
|
$message = $db->fetch($sql, ['mid1' => $messageId, 'mid2' => $messageId]);
|
|
|
|
if (!$message) {
|
|
http_response_code(404);
|
|
echo json_encode(['success' => false, 'error' => 'Mensaje no encontrado']);
|
|
exit;
|
|
}
|
|
|
|
// Solo permitir eliminar mensajes salientes (outgoing) a menos que sea admin
|
|
$isAdmin = isset($_SESSION['admin_logged_in']) && $_SESSION['admin_logged_in'];
|
|
if ($message['direction'] !== 'outgoing' && !$isAdmin) {
|
|
http_response_code(403);
|
|
echo json_encode(['success' => false, 'error' => 'Solo puedes eliminar tus propios mensajes']);
|
|
exit;
|
|
}
|
|
|
|
$deletedMessageId = $message['id'];
|
|
$userId = $message['user_id'];
|
|
$waMessageId = $message['wa_message_id'];
|
|
|
|
if ($softDelete) {
|
|
// Soft delete: marcar como eliminado pero mantener registro
|
|
// Verificar si existen las columnas deleted_at y original_content
|
|
$hasDeletedAt = false;
|
|
$hasOriginalContent = false;
|
|
try {
|
|
$columns = $db->fetchAll("SHOW COLUMNS FROM conversations WHERE Field IN ('deleted_at', 'original_content')");
|
|
foreach ($columns as $col) {
|
|
if ($col['Field'] === 'deleted_at') $hasDeletedAt = true;
|
|
if ($col['Field'] === 'original_content') $hasOriginalContent = true;
|
|
}
|
|
} catch (Exception $e) {
|
|
// Ignorar
|
|
}
|
|
|
|
// Construir la query según las columnas disponibles
|
|
// IMPORTANTE: Guardar original_content ANTES de modificar content
|
|
if ($hasDeletedAt && $hasOriginalContent) {
|
|
// Primero guardamos el contenido original
|
|
$db->execute("UPDATE conversations SET original_content = content WHERE id = :id AND original_content IS NULL", ['id' => $deletedMessageId]);
|
|
// Luego marcamos como eliminado
|
|
$updateSql = "UPDATE conversations SET content = '[Mensaje eliminado]', deleted_at = NOW() WHERE id = :id";
|
|
} elseif ($hasDeletedAt) {
|
|
$updateSql = "UPDATE conversations SET content = '[Mensaje eliminado]', deleted_at = NOW() WHERE id = :id";
|
|
} else {
|
|
$updateSql = "UPDATE conversations SET content = '[Mensaje eliminado]' WHERE id = :id";
|
|
}
|
|
|
|
$db->execute($updateSql, ['id' => $deletedMessageId]);
|
|
|
|
error_log("Message soft-deleted: ID={$deletedMessageId}, User={$userId}");
|
|
} else {
|
|
// Hard delete: eliminar completamente
|
|
|
|
// Primero, eliminar archivos multimedia asociados si existen
|
|
if (!empty($message['local_file'])) {
|
|
$filePath = dirname(__DIR__) . '/' . $message['local_file'];
|
|
if (file_exists($filePath)) {
|
|
@unlink($filePath);
|
|
error_log("Deleted media file: {$filePath}");
|
|
}
|
|
}
|
|
|
|
if (!empty($message['local_thumb'])) {
|
|
$thumbPath = dirname(__DIR__) . '/' . $message['local_thumb'];
|
|
if (file_exists($thumbPath)) {
|
|
@unlink($thumbPath);
|
|
error_log("Deleted thumbnail: {$thumbPath}");
|
|
}
|
|
}
|
|
|
|
// Eliminar el mensaje de la base de datos
|
|
$deleteSql = "DELETE FROM conversations WHERE id = :id";
|
|
$db->execute($deleteSql, ['id' => $deletedMessageId]);
|
|
|
|
error_log("Message hard-deleted: ID={$deletedMessageId}, User={$userId}");
|
|
}
|
|
|
|
// Intentar notificar por SSE si está disponible
|
|
try {
|
|
$ssePayload = [
|
|
'type' => 'message_deleted',
|
|
'user_id' => $userId,
|
|
'message_id' => $deletedMessageId,
|
|
'wa_message_id' => $waMessageId,
|
|
'soft_delete' => $softDelete,
|
|
'deleted_at' => date('Y-m-d H:i:s')
|
|
];
|
|
|
|
// Llamar al endpoint push_event interno
|
|
$pushUrl = 'http://127.0.0.1' . dirname($_SERVER['SCRIPT_NAME']) . '/push_event.php';
|
|
$ch = curl_init($pushUrl);
|
|
curl_setopt($ch, CURLOPT_POST, true);
|
|
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
|
|
'event_type' => 'message_deleted',
|
|
'data' => $ssePayload,
|
|
'target_user_id' => 'all'
|
|
]));
|
|
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
|
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
|
curl_setopt($ch, CURLOPT_TIMEOUT, 2);
|
|
curl_exec($ch);
|
|
curl_close($ch);
|
|
} catch (Exception $sseErr) {
|
|
error_log("delete_message: SSE notification failed: " . $sseErr->getMessage());
|
|
}
|
|
|
|
echo json_encode([
|
|
'success' => true,
|
|
'message' => $softDelete ? 'Mensaje eliminado' : 'Mensaje eliminado permanentemente',
|
|
'data' => [
|
|
'id' => $deletedMessageId,
|
|
'message_id' => $waMessageId,
|
|
'soft_delete' => $softDelete,
|
|
'deleted_at' => date('Y-m-d H:i:s')
|
|
]
|
|
]);
|
|
|
|
} catch (Exception $e) {
|
|
error_log('delete_message.php error: ' . $e->getMessage() . ' | Trace: ' . $e->getTraceAsString());
|
|
http_response_code(500);
|
|
echo json_encode(['success' => false, 'error' => 'Error interno del servidor', 'debug' => $e->getMessage()]);
|
|
}
|