' . htmlspecialchars($buttonText) . ' '; } // Inhalt: Zeilenumbrüche in
umwandeln, aber vorhandenes HTML beibehalten $inhaltHtml = nl2br(htmlspecialchars($inhalt)); $datum = date('d.m.Y, H:i') . ' Uhr'; // Logo-URL dynamisch ermitteln $host = $_SERVER['HTTP_HOST'] ?? intranet_env('INTRANET_FQDN'); $logoUrl = 'https://' . $host . '/intranet_repo/projects/_central/img/nak-logo.svg'; return '
' . $buttonHtml . '
NAK
Neuapostolische Kirche
Gemeinde Reinickendorf
' . htmlspecialchars($betreff) . '
' . $inhaltHtml . '
Gesendet am ' . $datum . '
Intranet NAK Reinickendorf · Automatische Benachrichtigung
'; } /** * Sendet eine HTML-E-Mail über SMTP. * * @param string $empfaenger Empfänger * @param string $betreff Betreff * @param string $nachricht Klartext-Nachricht (wird ins HTML-Template eingebettet) * @param string|null $cc CC-Adresse * @param string $absender Absender * @param string|null $buttonText Optionaler Button-Text * @param string|null $buttonUrl Optionale Button-URL * @return bool */ function send_intranet_mail( string $empfaenger, string $betreff, string $nachricht, ?string $cc = null, string $absender = "intranet@nak-reinickendorf.de", ?string $buttonText = null, ?string $buttonUrl = null ): bool { $htmlBody = build_html_mail($betreff, $nachricht, $buttonText, $buttonUrl); // MIME-Header $boundary = 'boundary_' . bin2hex(random_bytes(16)); $msgId = '<' . bin2hex(random_bytes(16)) . '@nak-reinickendorf.de>'; $headers = "From: Intranet NAK Reinickendorf <{$absender}>\r\n"; $headers .= "Reply-To: {$absender}\r\n"; $headers .= "To: {$empfaenger}\r\n"; if (!empty($cc)) { $headers .= "Cc: {$cc}\r\n"; } $headers .= "Subject: =?UTF-8?B?" . base64_encode($betreff) . "?=\r\n"; $headers .= "Message-ID: {$msgId}\r\n"; $headers .= "MIME-Version: 1.0\r\n"; $headers .= "Content-Type: multipart/alternative; boundary=\"{$boundary}\"\r\n"; $headers .= "X-Mailer: Intranet-NAK-Reinickendorf/1.0\r\n"; $headers .= "Date: " . date('r') . "\r\n"; // Plaintext-Fallback $plainBody = strip_tags($nachricht); // Multipart Body $body = "--{$boundary}\r\n"; $body .= "Content-Type: text/plain; charset=utf-8\r\n"; $body .= "Content-Transfer-Encoding: 8bit\r\n\r\n"; $body .= $plainBody . "\r\n\r\n"; $body .= "--{$boundary}\r\n"; $body .= "Content-Type: text/html; charset=utf-8\r\n"; $body .= "Content-Transfer-Encoding: 8bit\r\n\r\n"; $body .= $htmlBody . "\r\n\r\n"; $body .= "--{$boundary}--\r\n"; $message = $headers . "\r\n" . $body; $recipients = [$empfaenger]; if (!empty($cc)) { $recipients[] = $cc; } return smtp_send(SMTP_HOST, SMTP_PORT, SMTP_USER, SMTP_PASS, $absender, $recipients, $message); } /** * Direkter SMTP-Versand mit STARTTLS und AUTH LOGIN. */ function smtp_send(string $host, int $port, string $user, string $pass, string $from, array $to, string $data): bool { $errno = 0; $errstr = ''; $socket = @stream_socket_client("tcp://{$host}:{$port}", $errno, $errstr, 30); if (!$socket) { error_log("SMTP connect failed: {$errstr} ({$errno})"); return false; } stream_set_timeout($socket, 30); $response = smtp_read($socket); if (substr($response, 0, 3) !== '220') { fclose($socket); return false; } smtp_write($socket, "EHLO " . gethostname()); $response = smtp_read($socket); if (substr($response, 0, 3) !== '250') { fclose($socket); return false; } smtp_write($socket, "STARTTLS"); $response = smtp_read($socket); if (substr($response, 0, 3) !== '220') { fclose($socket); return false; } $crypto = stream_socket_enable_crypto($socket, true, STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT | STREAM_CRYPTO_METHOD_TLSv1_3_CLIENT); if (!$crypto) { error_log("SMTP STARTTLS failed"); fclose($socket); return false; } smtp_write($socket, "EHLO " . gethostname()); $response = smtp_read($socket); if (substr($response, 0, 3) !== '250') { fclose($socket); return false; } smtp_write($socket, "AUTH LOGIN"); $response = smtp_read($socket); if (substr($response, 0, 3) !== '334') { fclose($socket); return false; } smtp_write($socket, base64_encode($user)); $response = smtp_read($socket); if (substr($response, 0, 3) !== '334') { fclose($socket); return false; } smtp_write($socket, base64_encode($pass)); $response = smtp_read($socket); if (substr($response, 0, 3) !== '235') { error_log("SMTP auth failed: {$response}"); fclose($socket); return false; } smtp_write($socket, "MAIL FROM:<{$from}>"); $response = smtp_read($socket); if (substr($response, 0, 3) !== '250') { fclose($socket); return false; } foreach ($to as $recipient) { smtp_write($socket, "RCPT TO:<{$recipient}>"); $response = smtp_read($socket); if (substr($response, 0, 3) !== '250') { fclose($socket); return false; } } smtp_write($socket, "DATA"); $response = smtp_read($socket); if (substr($response, 0, 3) !== '354') { fclose($socket); return false; } $data = str_replace("\r\n.", "\r\n..", $data); fwrite($socket, $data . "\r\n.\r\n"); $response = smtp_read($socket); if (substr($response, 0, 3) !== '250') { fclose($socket); return false; } smtp_write($socket, "QUIT"); smtp_read($socket); fclose($socket); return true; } function smtp_write($socket, string $cmd): void { fwrite($socket, $cmd . "\r\n"); } function smtp_read($socket): string { $response = ''; while ($line = fgets($socket, 512)) { $response .= $line; if (isset($line[3]) && $line[3] === ' ') break; if (strlen($line) < 4) break; } return $response; } /** * Ermittelt alle E-Mail-Adressen von Nutzern, die BEIDE angegebenen Rollen besitzen. * Benötigt eine bestehende $pdo-Verbindung. * * @param PDO $pdo Datenbankverbindung * @param array $roles Array von Rollennamen, die alle erfüllt sein müssen * @return array Liste der E-Mail-Adressen */ function get_emails_by_roles(PDO $pdo, array $roles): array { if (empty($roles)) return []; $conditions = []; foreach ($roles as $role) { $conditions[] = '"' . str_replace('"', '""', $role) . '" = 1'; } $where = implode(' AND ', $conditions); $sql = "SELECT ugi.mail FROM user_permissions up INNER JOIN user_general_information ugi ON up.user_id = ugi.user_id WHERE {$where} AND ugi.mail IS NOT NULL AND ugi.mail != ''"; $result = $pdo->query($sql); $emails = []; if ($result) { while ($row = $result->fetch()) { $emails[] = $row['mail']; } } return $emails; } /** * Sendet eine Mail an alle Nutzer mit den Rollen Admin UND Technik (Sammelmail). * * @param PDO $pdo Datenbankverbindung * @param string $betreff Betreff * @param string $nachricht Nachricht * @param string|null $buttonText Optionaler Button-Text * @param string|null $buttonUrl Optionale Button-URL * @return bool True wenn mindestens eine Mail gesendet wurde */ function send_admin_team_mail( PDO $pdo, string $betreff, string $nachricht, ?string $buttonText = null, ?string $buttonUrl = null ): bool { $emails = get_emails_by_roles($pdo, ['Admin', 'Technik']); if (empty($emails)) { // Fallback auf ADMIN_EMAIL return send_intranet_mail(ADMIN_EMAIL, $betreff, $nachricht, null, "intranet@nak-reinickendorf.de", $buttonText, $buttonUrl); } $success = false; foreach ($emails as $email) { if (send_intranet_mail($email, $betreff, $nachricht, null, "intranet@nak-reinickendorf.de", $buttonText, $buttonUrl)) { $success = true; } } return $success; } /** * Sendet eine Mail an alle Nutzer mit der Rolle Brandschutzbeauftragter. * * @param PDO $pdo Datenbankverbindung * @param string $betreff Betreff * @param string $nachricht Nachricht * @param string|null $buttonText Optionaler Button-Text * @param string|null $buttonUrl Optionale Button-URL * @return bool True wenn mindestens eine Mail gesendet wurde */ function send_brandschutzbeauftragter_mail( PDO $pdo, string $betreff, string $nachricht, ?string $buttonText = null, ?string $buttonUrl = null ): bool { $emails = get_emails_by_roles($pdo, ['Brandschutzbeauftragter']); if (empty($emails)) return false; $success = false; foreach ($emails as $email) { if (send_intranet_mail($email, $betreff, $nachricht, null, "intranet@nak-reinickendorf.de", $buttonText, $buttonUrl)) { $success = true; } } return $success; } ?>