Files
sistema_funcionando_lastwar/includes/message_handler.php

361 lines
14 KiB
PHP
Executable File

<?php
// Configurar zona horaria
date_default_timezone_set('America/Mexico_City');
// Incluir el helper de programación
require_once __DIR__ . '/schedule_helpers.php';
// Configuración de logs
$logFile = dirname(__DIR__) . '/logs/discord_api.log';
// Crear el directorio de logs si no existe
if (!file_exists(dirname($logFile))) {
mkdir(dirname($logFile), 0755, true);
}
// Incluir archivos necesarios
require_once __DIR__ . '/session_check.php';
require_once __DIR__ . '/db.php';
require_once __DIR__ . '/activity_logger.php';
$submitAction = $_POST['submit'] ?? '';
// --- Special handler for sending from a template ---
if ($submitAction === 'send_from_template') {
$template_id = $_POST['recurrent_message_id'] ?? 0;
$user_ids = $_POST['recipientId_user'] ?? [];
$scheduleType = $_POST['scheduleType'] ?? 'now';
$scheduleDateTime = $_POST['scheduleDateTime'] ?? null;
$userId = $_SESSION['user_id'];
if (empty($template_id) || empty($user_ids)) {
header("Location: ../enviar_plantilla.php?error=missing_fields");
exit();
}
$pdo->beginTransaction();
try {
// Fetch the message content from the template
$stmt = $pdo->prepare("SELECT message_content FROM recurrent_messages WHERE id = ?");
$stmt->execute([$template_id]);
$template = $stmt->fetch(PDO::FETCH_ASSOC);
if (!$template) {
throw new Exception("La plantilla seleccionada no existe.");
}
$messageContent = $template['message_content'];
// 1. Insert the main message content into the messages table
$stmt = $pdo->prepare("INSERT INTO messages (user_id, content) VALUES (?, ?)");
$stmt->execute([$userId, $messageContent]);
$messageId = $pdo->lastInsertId();
// 2. Determine the send time
$sendTime = ($scheduleType === 'later')
? (new DateTime($scheduleDateTime, new DateTimeZone('America/Mexico_City')))->format('Y-m-d H:i:s')
: date('Y-m-d H:i:s');
// 3. Create a schedule for each selected user
$stmt = $pdo->prepare(
"INSERT INTO schedules (message_id, recipient_id, send_time, status, is_recurring, recurring_days, recurring_time)
VALUES (?, ?, ?, 'pending', 0, NULL, NULL)"
);
foreach ($user_ids as $user_id) {
$stmt->execute([$messageId, $user_id, $sendTime]);
log_activity($userId, 'Message Scheduled from Template', 'Schedule for user ID: ' . $user_id);
}
$pdo->commit();
// If sending now, trigger the queue processor
if ($scheduleType === 'now') {
$phpPath = PHP_BINARY ?: 'php';
$scriptPath = dirname(__DIR__) . '/process_queue.php';
$logPath = dirname(__DIR__) . '/logs/process_queue_manual.log';
$command = sprintf('%s %s >> %s 2>&1 &', escapeshellarg($phpPath), escapeshellarg($scriptPath), escapeshellarg($logPath));
shell_exec($command);
}
header("Location: ../scheduled_messages.php?success=template_sent");
exit();
} catch (Exception $e) {
$pdo->rollBack();
error_log("TemplateHandler Error: " . $e->getMessage() . "\n", 3, dirname(__DIR__) . '/logs/discord_api.log');
header("Location: ../enviar_plantilla.php?error=dberror");
exit();
}
}
// Regular message handling starts here
if ($_SERVER['REQUEST_METHOD'] !== 'POST') {
header('Location: ../index.php');
exit();
}
$userId = $_SESSION['user_id'];
$content = $_POST['messageContent'] ?? '';
error_log("[DEBUG] Message content in message_handler.php: " . substr($content, 0, 500)); // Log first 500 chars
$platform = $_POST['platform'] ?? ''; // 'discord' or 'telegram'
// Obtener canales y usuarios seleccionados (pueden ser arrays JSON)
$channelIds = json_decode($_POST['channelIds'] ?? '[]', true);
$userIds = json_decode($_POST['userIds'] ?? '[]', true);
// Si no hay canales ni usuarios seleccionados, verificar el campo legacy recipientId
if (empty($channelIds) && empty($userIds) && !empty($_POST['recipientId'])) {
// Para compatibilidad con el código existente
$channelIds = [$_POST['recipientId']];
}
// Combinar todos los IDs de destinatarios y eliminar valores vacíos
$allRecipientIds = array_filter(array_merge($channelIds, $userIds));
// Debug: Registrar los destinatarios recibidos
error_log("Channel IDs: " . print_r($channelIds, true));
error_log("User IDs: " . print_r($userIds, true));
error_log("All Recipient IDs: " . print_r($allRecipientIds, true));
// Validar que haya al menos un destinatario
if (empty($allRecipientIds)) {
header('Location: ../create_message.php?error=no_recipients');
exit();
}
$scheduleId = $_POST['schedule_id'] ?? null;
$submitAction = $_POST['submit'] ?? 'send';
$isEditing = ($submitAction === 'update' && !empty($scheduleId));
// Basic validation
if (empty($content) || empty($platform) || empty(array_filter($allRecipientIds))) {
$error_param = 'missing_fields';
if (empty($platform)) $error_param = 'missing_platform';
if (empty(array_filter($allRecipientIds))) $error_param = 'missing_recipient';
$error_url = $isEditing
? "../create_message.php?action=edit&schedule_id={$scheduleId}&error={$error_param}"
: "../create_message.php?error={$error_param}";
header("Location: {$error_url}");
exit();
}
$scheduleType = $_POST['scheduleType'] ?? 'now';
$pdo->beginTransaction();
try {
// --- DEBUG LOGGING ---
$debugLogFile = dirname(__DIR__) . '/logs/schedule_debug.log';
$logEntry = "[" . date('Y-m-d H:i:s') . "] --- INICIO DE PETICIÓN ---\n";
$logEntry .= "ACTION: {$submitAction}, SCHEDULE_ID: " . ($scheduleId ?? 'null') . "\n";
$logEntry .= "PLATFORM: {$platform}\n";
$logEntry .= "CHANNEL_IDS: " . (is_array($channelIds) ? implode(', ', $channelIds) : $channelIds) . "\n";
$logEntry .= "USER_IDS: " . (is_array($userIds) ? implode(', ', $userIds) : $userIds) . "\n";
$logEntry .= "CONTENT LENGTH: " . strlen($content) . "\n";
$logEntry .= "POST DATA: " . json_encode($_POST, JSON_PRETTY_PRINT) . "\n";
file_put_contents($debugLogFile, $logEntry, FILE_APPEND);
// --- FIN DEBUG LOGGING ---
// Validar que haya contenido y destinatarios
if (empty(trim($content))) {
throw new Exception("El contenido del mensaje no puede estar vacío.");
}
if (empty($channelIds) && empty($userIds)) {
throw new Exception("Debes seleccionar al menos un canal o usuario como destinatario.");
}
// Combinar todos los IDs de destinatarios
$allRecipientIds = array_merge(
is_array($channelIds) ? $channelIds : [],
is_array($userIds) ? $userIds : []
);
// Validar que todos los destinatarios existan
if (!empty($allRecipientIds)) {
$placeholders = rtrim(str_repeat('?,', count($allRecipientIds)), ',');
$stmt = $pdo->prepare("SELECT COUNT(*) FROM recipients WHERE id IN ($placeholders)");
$stmt->execute($allRecipientIds);
$validRecipients = (int)$stmt->fetchColumn();
if ($validRecipients !== count($allRecipientIds)) {
throw new Exception("Uno o más destinatarios no son válidos.");
}
}
if ($submitAction === 'update' && !empty($scheduleId)) {
// UPDATE LOGIC
$stmt = $pdo->prepare("SELECT message_id FROM schedules WHERE id = ?");
$stmt->execute([$scheduleId]);
$originalMessage = $stmt->fetch();
if (!$originalMessage) {
throw new Exception("No se encontró la programación original.");
}
$messageId = $originalMessage['message_id'];
$stmt = $pdo->prepare("UPDATE messages SET content = ? WHERE id = ?");
$stmt->execute([$content, $messageId]);
$sendTime = null;
$isRecurring = 0;
$recurringDaysStr = null;
$recurringTime = null;
$status = 'pending';
$stmt = $pdo->prepare("DELETE FROM schedules WHERE message_id = ?");
$stmt->execute([$originalMessage['message_id']]);
// Obtener la configuración de programación
$sendTime = null;
$status = 'pending';
$isRecurring = 0;
$recurringDaysStr = null;
$recurringTime = null;
if ($scheduleType === 'later') {
$user_timezone = new DateTimeZone('America/Mexico_City');
$schedule_dt = DateTime::createFromFormat('Y-m-d\TH:i', $_POST['scheduleDateTime'], $user_timezone);
if (!$schedule_dt) {
throw new Exception("Formato de fecha/hora de programación no válido.");
}
$sendTime = $schedule_dt->format('Y-m-d H:i:s');
} elseif ($scheduleType === 'recurring') {
$isRecurring = 1;
$recurringDays = $_POST['recurringDays'] ?? [];
sort($recurringDays);
$recurringDaysStr = !empty($recurringDays) ? implode(',', $recurringDays) : null;
$recurringTime = $_POST['recurringTime'] ?? '00:00';
$sendTime = calculateNextSendTime($recurringDays, $recurringTime);
} else { // 'now'
$sendTime = date('Y-m-d H:i:s');
}
// Create new schedules for each recipient
$stmt = $pdo->prepare(
"INSERT INTO schedules (message_id, recipient_id, send_time, status, is_recurring, recurring_days, recurring_time) VALUES (?, ?, ?, ?, ?, ?, ?)"
);
foreach ($allRecipientIds as $recipientId) {
$stmt->execute([
$originalMessage['message_id'],
$recipientId,
$sendTime,
$status,
$isRecurring,
$recurringDaysStr,
$recurringTime
]);
log_activity($userId, 'Schedule Recipient Updated', 'Schedule for Message ID: ' . $originalMessage['message_id'] . ' to Recipient ID: ' . $recipientId);
}
// --- DEBUG LOGGING ---
$logEntry = "Calculated sendTime for UPDATE: {$sendTime} (Timezone: " . date_default_timezone_get() . ")\n";
file_put_contents($debugLogFile, $logEntry, FILE_APPEND);
// --- FIN DEBUG LOGGING ---
$success_param = 'updated';
log_activity($userId, 'Message Updated', 'Schedule ID: ' . $scheduleId);
} else {
// CREATE LOGIC
$sendTime = null;
$status = 'pending';
$isRecurring = 0;
$recurringDaysStr = null;
$recurringTime = null;
// Determinar la configuración de programación
if ($scheduleType === 'later') {
$user_timezone = new DateTimeZone('America/Mexico_City');
$schedule_dt = DateTime::createFromFormat('Y-m-d\TH:i', $_POST['scheduleDateTime'], $user_timezone);
if (!$schedule_dt) {
throw new Exception("Formato de fecha/hora de programación no válido.");
}
$sendTime = $schedule_dt->format('Y-m-d H:i:s');
} elseif ($scheduleType === 'recurring') {
$isRecurring = 1;
$recurringDays = $_POST['recurringDays'] ?? [];
sort($recurringDays);
$recurringDaysStr = !empty($recurringDays) ? implode(',', $recurringDays) : null;
$recurringTime = $_POST['recurringTime'] ?? '00:00';
$sendTime = calculateNextSendTime($recurringDays, $recurringTime);
} else { // 'now'
$sendTime = date('Y-m-d H:i:s');
}
// Insertar un solo mensaje
$stmt = $pdo->prepare("INSERT INTO messages (user_id, content) VALUES (?, ?)");
$stmt->execute([$userId, $content]);
$messageId = $pdo->lastInsertId();
// Crear programaciones para cada destinatario
$stmt = $pdo->prepare(
"INSERT INTO schedules (message_id, recipient_id, send_time, status, is_recurring, recurring_days, recurring_time) " .
"VALUES (?, ?, ?, ?, ?, ?, ?)"
);
// Combinar canales y usuarios en un solo array
$allRecipients = array_merge(
is_array($channelIds) ? $channelIds : [],
is_array($userIds) ? $userIds : []
);
// Crear una programación para cada destinatario
foreach ($allRecipients as $recipientId) {
$stmt->execute([
$messageId,
$recipientId,
$sendTime,
$status,
$isRecurring,
$recurringDaysStr,
$recurringTime
]);
$scheduleId = $pdo->lastInsertId();
log_activity($userId, 'Message Created', 'Schedule ID: ' . $scheduleId . ' for Recipient ID: ' . $recipientId);
}
$success_param = 'message_created';
// --- DEBUG LOGGING ---
$logEntry = "Calculated sendTime for CREATE: {$sendTime} (Timezone: " . date_default_timezone_get() . ")\n-- FIN DE PETICIÓN --\n\n";
file_put_contents($debugLogFile, $logEntry, FILE_APPEND);
// --- FIN DEBUG LOGGING ---
}
$pdo->commit();
if ($scheduleType === 'now') {
$phpPath = PHP_BINARY ?: 'php';
$scriptPath = dirname(__DIR__) . '/process_queue.php';
$logPath = dirname(__DIR__) . '/logs/process_queue_manual.log';
// Asegurarse de que se use el entorno correcto
$command = sprintf(
'APP_ENVIRONMENT=pruebas %s %s >> %s 2>&1 &',
escapeshellarg($phpPath),
escapeshellarg($scriptPath),
escapeshellarg($logPath)
);
// Registrar el comando que se va a ejecutar para depuración
error_log("Ejecutando comando: " . $command . "\n", 3, $logFile);
// Ejecutar el comando
shell_exec($command);
// Registrar que se inició el procesamiento
error_log("Procesamiento en segundo plano iniciado para schedule_id: " . ($scheduleId ?? 'nuevo') . "\n", 3, $logFile);
}
header("Location: ../scheduled_messages.php?success={$success_param}");
exit();
} catch (Exception $e) {
$pdo->rollBack();
error_log("MessageHandler Error: " . $e->getMessage() . "\n", 3, $logFile);
$error_url = ($submitAction === 'update') ? "../create_message.php?action=edit&schedule_id={$scheduleId}&error=dberror" : '../create_message.php?error=dberror';
header("Location: {$error_url}");
exit();
}
?>