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(); } ?>