|
' . 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 '
|
Neuapostolische Kirche
Gemeinde Reinickendorf
|
|
|
' . htmlspecialchars($betreff) . '
|
|
' . $inhaltHtml . '
|
' . $buttonHtml . '
|
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;
}
?>