togethere.cloud/public_html/includes/smtp_helper.php

144 lines
4.7 KiB
PHP

<?php
/**
* Wysyłka emaili przez SMTP z obsługą STARTTLS (port 587) i SSL (port 465)
*/
function sendEmailSMTP($to, $subject, $html_body, $config = null) {
$log_file = __DIR__ . '/smtp_debug.log';
file_put_contents($log_file, date('Y-m-d H:i:s') . " - Function called for: $to\n", FILE_APPEND);
if ($config === null) {
$config = require __DIR__ . '/smtp_config.php';
}
$log = [];
$log[] = date('Y-m-d H:i:s') . " - Starting SMTP to: $to";
$encryption = strtolower($config['encryption'] ?? 'tls');
$host = $config['host'];
$port = (int)$config['port'];
// Funkcja odczytu pełnej odpowiedzi SMTP (wieloliniowej)
$read = function($sock) {
$out = '';
while ($line = fgets($sock, 515)) {
$out .= $line;
if (preg_match('/^\d{3} /', $line)) break;
}
return $out;
};
if ($encryption === 'ssl') {
$ctx = stream_context_create(['ssl' => ['verify_peer' => false, 'verify_peer_name' => false]]);
$sock = @stream_socket_client("ssl://{$host}:{$port}", $errno, $errstr, 30, STREAM_CLIENT_CONNECT, $ctx);
} else {
// TLS/STARTTLS — najpierw plain socket, potem STARTTLS
$sock = @stream_socket_client("tcp://{$host}:{$port}", $errno, $errstr, 30);
}
if (!$sock) {
$log[] = "Connection FAILED: $errstr ($errno)";
file_put_contents($log_file, implode("\n", $log) . "\n\n", FILE_APPEND);
return false;
}
stream_set_timeout($sock, 30);
$log[] = "Connected to {$host}:{$port} ({$encryption})";
$resp = $read($sock);
$log[] = "Server: " . trim($resp);
fwrite($sock, "EHLO {$host}\r\n");
$resp = $read($sock);
$log[] = "EHLO: " . trim($resp);
// STARTTLS dla TLS/port 587
if ($encryption === 'tls') {
fwrite($sock, "STARTTLS\r\n");
$resp = $read($sock);
$log[] = "STARTTLS: " . trim($resp);
if (strpos($resp, '220') === false) {
$log[] = "STARTTLS not accepted";
file_put_contents($log_file, implode("\n", $log) . "\n\n", FILE_APPEND);
fclose($sock);
return false;
}
// Upgrade do TLS
$ctx = stream_context_create(['ssl' => ['verify_peer' => false, 'verify_peer_name' => false]]);
if (!stream_socket_enable_crypto($sock, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
$log[] = "TLS upgrade FAILED";
file_put_contents($log_file, implode("\n", $log) . "\n\n", FILE_APPEND);
fclose($sock);
return false;
}
$log[] = "TLS upgraded OK";
// EHLO ponownie po TLS
fwrite($sock, "EHLO {$host}\r\n");
$resp = $read($sock);
$log[] = "EHLO2: " . trim($resp);
}
fwrite($sock, "AUTH LOGIN\r\n");
$resp = $read($sock);
$log[] = "AUTH: " . trim($resp);
fwrite($sock, base64_encode($config['username']) . "\r\n");
$resp = $read($sock);
$log[] = "USER: " . trim($resp);
fwrite($sock, base64_encode($config['password']) . "\r\n");
$resp = $read($sock);
$log[] = "PASS: " . trim($resp);
if (strpos($resp, '235') === false) {
$log[] = "Auth FAILED";
file_put_contents($log_file, implode("\n", $log) . "\n\n", FILE_APPEND);
fclose($sock);
return false;
}
// MAIL FROM
fwrite($sock, "MAIL FROM: <{$config['from_email']}>\r\n");
$resp = $read($sock);
$log[] = "FROM: " . trim($resp);
// RCPT TO
fwrite($sock, "RCPT TO: <{$to}>\r\n");
$resp = $read($sock);
$log[] = "TO: " . trim($resp);
// DATA
fwrite($sock, "DATA\r\n");
$resp = $read($sock);
$log[] = "DATA: " . trim($resp);
$msgId = '<' . time() . '.' . rand(1000, 9999) . '@' . $host . '>';
$headers = "From: {$config['from_name']} <{$config['from_email']}>\r\n";
$headers .= "To: <{$to}>\r\n";
$headers .= "Subject: =?UTF-8?B?" . base64_encode($subject) . "?=\r\n";
$headers .= "Message-ID: {$msgId}\r\n";
$headers .= "Date: " . date('r') . "\r\n";
$headers .= "MIME-Version: 1.0\r\n";
$headers .= "Content-Type: text/html; charset=UTF-8\r\n";
$headers .= "\r\n";
fwrite($sock, $headers . $html_body . "\r\n.\r\n");
$resp = $read($sock);
$log[] = "SEND: " . trim($resp);
fwrite($sock, "QUIT\r\n");
$resp = $read($sock);
$log[] = "QUIT: " . trim($resp);
fclose($sock);
$success = strpos($log[count($log) - 2], '250') !== false;
$log[] = "Result: " . ($success ? "SUCCESS" : "FAILED");
file_put_contents($log_file, implode("\n", $log) . "\n\n", FILE_APPEND);
return $success;
}