144 lines
4.7 KiB
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;
|
|
}
|