Code: Alles auswählen
<?php
session_start();
// PHPMailer einbinden (falls via Composer installiert)
// require_once "vendor/autoload.php";
// Alternativ: PHPMailer manuell einbinden (falls embedded verwendet wird)
require_once "PHPMailer/src/Exception.php";
require_once "PHPMailer/src/PHPMailer.php";
require_once "PHPMailer/src/SMTP.php";
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\SMTP;
use PHPMailer\PHPMailer\Exception;
// =============================================================
// KONFIGURATION - Hier können Sie Ihre Einstellungen anpassen
// =============================================================
// Grundeinstellungen
$recipient_email = "entfernt";
$sender_name = "Kontaktformular";
$success_message = "Vielen Dank für Ihre Nachricht!";
// SMTP-Konfiguration - Nur ausfüllen wenn Sie SMTP verwenden möchten:
// Lassen Sie diese Werte auskommentiert für normalen E-Mail-Versand über PHPMailer ohne SMTP
$smtp_host = "smtp.ionos.de"; // Ihr SMTP-Server
$smtp_port = 465; // SMTP-Port (587 für TLS, 465 für SSL)
$smtp_secure = "ssl"; // Verschlüsselung: "tls" oder "ssl"
$smtp_user = "entfernt"; // Ihr SMTP-Benutzername
$smtp_pass = "entfernt"; // Ihr SMTP-Passwort
$smtp_from_name = "entfernt"; // Name des Absenders
// Automatische Antwort-Einstellungen
$enable_auto_reply = false;
$auto_reply_subject = "Ihre Nachricht wurde erhalten";
$auto_reply_message = "Hallo,
vielen Dank für Ihre Nachricht. Wir haben Ihre Anfrage erhalten und werden uns schnellstmöglich bei Ihnen melden.
Mit freundlichen Grüßen
Ihr Team";
$auto_reply_include_original = true;
$auto_reply_html_format = false;
$auto_reply_sender_name = "Support-Team";
// Datei-Upload-Einstellungen
$allowed_extensions = ["jpg", "png", "pdf", "doc", "docx"];
$max_filesize_mb = 5;
$uploads_dir = "uploads/";
// =============================================================
// HILFSFUNKTIONEN
// =============================================================
// Funktion zur Bereinigung von Eingabedaten
function sanitize_input($data) {
$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data, ENT_QUOTES, "UTF-8");
return $data;
}
// Funktion zur Validierung der SMTP-Konfiguration
function validateSmtpConfig() {
global $smtp_host, $smtp_user, $smtp_pass, $smtp_port, $smtp_secure;
$required_fields = ["smtp_host", "smtp_user", "smtp_pass"];
foreach ($required_fields as $field) {
if (!isset($GLOBALS[$field]) || empty($GLOBALS[$field])) {
return false;
}
}
// Port-Validierung
if (isset($smtp_port) && (!is_numeric($smtp_port) || $smtp_port < 1 || $smtp_port > 65535)) {
return false;
}
// Verschlüsselung-Validierung
if (isset($smtp_secure) && !in_array($smtp_secure, ["tls", "ssl"])) {
return false;
}
return true;
}
// Funktion zur Konfiguration des PHPMailer-Objekts
function configurePHPMailer($mail, $sender_name, $recipient_email) {
global $smtp_host, $smtp_user, $smtp_pass, $smtp_port, $smtp_secure, $smtp_from_name;
try {
// SMTP-Konfiguration prüfen
if (validateSmtpConfig()) {
// SMTP verwenden
$mail->isSMTP();
$mail->Host = $smtp_host;
$mail->SMTPAuth = true;
$mail->Username = $smtp_user;
$mail->Password = $smtp_pass;
// Debugging (nur für Entwicklung aktivieren)
// $mail->SMTPDebug = SMTP::DEBUG_SERVER;
$mail->SMTPOptions = array(
"ssl" => array(
"verify_peer" => false,
"verify_peer_name" => false,
"allow_self_signed" => true
)
);
// Verschlüsselung und Port
if (isset($smtp_secure) && $smtp_secure === "ssl") {
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
$mail->Port = isset($smtp_port) ? (int)$smtp_port : 465;
} else {
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = isset($smtp_port) ? (int)$smtp_port : 587;
}
// Timeout-Einstellungen
$mail->Timeout = 30;
$mail->SMTPKeepAlive = false;
// Absender für SMTP
$from_name = isset($smtp_from_name) ? $smtp_from_name : $sender_name;
$mail->setFrom($smtp_user, $from_name);
return "smtp";
} else {
// Standard-Mail verwenden
$mail->isMail();
$mail->setFrom($recipient_email, $sender_name);
return "mail";
}
} catch (Exception $e) {
// Bei SMTP-Fehlern auf Standard-Mail zurückfallen
error_log("SMTP Configuration Error: " . $e->getMessage());
$mail->isMail();
$mail->setFrom($recipient_email, $sender_name);
return "fallback";
}
}
// =============================================================
// HAUPTVERARBEITUNG
// =============================================================
// Überprüfen, ob Daten gesendet wurden
if ($_SERVER["REQUEST_METHOD"] == "POST") {
// Anti-Spam: CSRF-Token-Überprüfung
if (!isset($_POST["csrf_token"]) || $_POST["csrf_token"] !== ($_SESSION["csrf_token"] ?? null)) {
http_response_code(400);
echo json_encode(["success" => false, "message" => "Sicherheitsfehler: Ungültiges Token."]);
exit;
}
// Anti-Spam: Honeypot-Überprüfung
if (!empty($_POST["name_hp"])) {
http_response_code(400);
echo json_encode(["success" => false, "message" => "Honeypot-Feld ausgefüllt, dies ist ein Spam-Versuch."]);
exit;
}
// Anti-Spam: Zeitbasierte Überprüfung (mind. 3 Sekunden)
$time_diff = time() - ($_SESSION["form_start_time"] ?? 0);
if ($time_diff < 3) {
http_response_code(400);
echo json_encode(["success" => false, "message" => "Formular zu schnell ausgefüllt."]);
exit;
}
// Validierung der Pflichtfelder und E-Mail-Validierung
$required_fields = ["name", "email", "Betreff", "Nachricht", "Datenschutz"];
$email_field_name = "";
// E-Mail-Feldname suchen
foreach ($_POST as $key => $value) {
if (strpos(strtolower($key), "email") !== false || strpos(strtolower($key), "mail") !== false) {
$email_field_name = $key;
break;
}
}
$errors = [];
foreach ($required_fields as $field_name) {
if (!empty($field_name) && (empty($_POST[$field_name]) && empty($_FILES[$field_name]["tmp_name"]))) {
$errors[] = $field_name;
}
}
// Zusätzliche E-Mail-Validierung, falls ein E-Mail-Feld gefunden wurde
if (!empty($email_field_name)) {
$email_value = $_POST[$email_field_name] ?? "";
if (!empty($email_value) && !filter_var($email_value, FILTER_VALIDATE_EMAIL)) {
$errors[] = $email_field_name; // Fügt das E-Mail-Feld zu den Fehlern hinzu
}
}
// CAPTCHA-Überprüfung
if (!isset($_POST["captcha"]) || strtoupper($_POST["captcha"]) !== ($_SESSION["captcha_code"] ?? null)) {
$errors[] = "captcha";
// Neuen CAPTCHA-Code generieren nach falschem Versuch
$captcha_code = "";
$characters = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
for ($i = 0; $i < 5; $i++) {
$captcha_code .= $characters[rand(0, strlen($characters) - 1)];
}
$_SESSION["captcha_code"] = $captcha_code;
}
if (!empty($errors)) {
http_response_code(400);
echo json_encode(["success" => false, "message" => "Bitte füllen Sie alle Pflichtfelder korrekt aus.", "errors" => $errors]);
exit;
}
// Absender-E-Mail ermitteln (für automatische Antwort und Kopie)
$sender_email = "";
foreach ($_POST as $key => $value) {
if (strpos(strtolower($key), "email") !== false || strpos(strtolower($key), "mail") !== false) {
$sanitized_value = filter_var(sanitize_input($value), FILTER_SANITIZE_EMAIL);
if (filter_var($sanitized_value, FILTER_VALIDATE_EMAIL)) {
$sender_email = $sanitized_value;
break;
}
}
}
// Kopie an Absender gewünscht prüfen
$send_copy_to_sender = isset($_POST["send_copy_to_sender"]) && $_POST["send_copy_to_sender"] === "1";
// E-Mail-Betreff basierend auf den ersten beiden sichtbaren Feldern (Anti-Spam-Felder überspringen)
$subject = "Neue Nachricht aus dem Formular";
if (!empty($_POST)) {
$skip_keys = ["csrf_token", "name_hp", "captcha", "send_copy_to_sender"];
$visible_values = [];
foreach ($_POST as $key => $value) {
if (in_array($key, $skip_keys, true)) continue;
if (is_array($value)) continue;
if (trim((string)$value) === "") continue;
$visible_values[] = $value;
}
$first_value = $visible_values[0] ?? reset($_POST);
$second_value = $visible_values[1] ?? next($_POST);
if (!empty($first_value)) {
$subject = "Nachricht von " . sanitize_input($first_value);
if (!empty($second_value) && $second_value !== $first_value) {
$subject .= " (" . sanitize_input($second_value) . ")";
}
}
}
// E-Mail-Inhalt als HTML-Tabelle erstellen
$mail_content_html = "
<div style=\"font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;\">
<h2 style=\"color: #333; border-bottom: 2px solid #007bff; padding-bottom: 10px;\">
Neue Nachricht aus dem Formular
</h2>
<p>Hallo,</p>
<p>Sie haben eine neue Nachricht aus dem Kontaktformular erhalten:</p>
<table style=\"border-collapse: collapse; width: 100%; border: 1px solid #ddd; margin: 20px 0;\">
<tbody>
";
// E-Mail-Inhalt als reiner Text erstellen
$mail_content_text = "Neue Nachricht aus dem Formular:\n\n";
foreach ($_POST as $key => $value) {
if ($key === "captcha" || $key === "csrf_token" || $key === "name_hp" || $key === "send_copy_to_sender") continue;
$label = ucfirst(str_replace(["_", "-"], " ", $key));
if (is_array($value)) {
$value_str = implode(", ", array_map("htmlspecialchars", $value));
$value_text = implode(", ", $value);
} else {
$value_str = sanitize_input($value);
$value_text = $value;
}
$mail_content_html .= "
<tr>
<td style=\"padding: 12px; border: 1px solid #ddd; background-color: #f8f9fa; width: 30%; font-weight: bold; vertical-align: top;\">" . $label . "</td>
<td style=\"padding: 12px; border: 1px solid #ddd; vertical-align: top;\">" . nl2br($value_str) . "</td>
</tr>
";
$mail_content_text .= $label . ": " . $value_text . "\n";
}
$mail_content_html .= "
</tbody>
</table>
</div>
";
// Dateiuploads verarbeiten
$uploaded_files = [];
if (!empty($_FILES)) {
foreach ($_FILES as $field_name => $file) {
if ($file["error"] === UPLOAD_ERR_OK) {
$file_name = sanitize_input(basename($file["name"]));
$file_ext = strtolower(pathinfo($file_name, PATHINFO_EXTENSION));
if (!in_array($file_ext, $allowed_extensions)) {
http_response_code(400);
echo json_encode(["success" => false, "message" => "Fehler: Dateityp " . htmlspecialchars($file_ext) . " nicht erlaubt."]);
exit;
}
if ($file["size"] > $max_filesize_mb * 1024 * 1024) {
http_response_code(400);
echo json_encode(["success" => false, "message" => "Fehler: Maximale Dateigröße von " . $max_filesize_mb . "MB überschritten."]);
exit;
}
// Eindeutigen Dateinamen erstellen und in den uploads-Ordner verschieben
$unique_file_name = uniqid() . "-" . $file_name;
$target_file = $uploads_dir . $unique_file_name;
if (move_uploaded_file($file["tmp_name"], $target_file)) {
$uploaded_files[] = [
"name" => $file_name,
"path" => $target_file,
"size" => $file["size"]
];
} else {
http_response_code(500);
echo json_encode(["success" => false, "message" => "Fehler beim Hochladen der Datei."]);
exit;
}
$mail_content_html .= "<p style=\"margin-top: 20px;\"><strong>Anhang:</strong> " . htmlspecialchars($file_name) . " (" . number_format($file["size"] / 1024, 1) . " KB)</p>";
$mail_content_text .= "\nAnhang: " . htmlspecialchars($file_name) . " (" . number_format($file["size"] / 1024, 1) . " KB)\n";
}
}
}
// =============================================================
// HAUPTMAIL VERSENDEN - VERBESSERTE VERSION
// =============================================================
$main_mail_sent = false;
$mail_method_used = "";
try {
$mail = new PHPMailer(true);
// Mail-Methode konfigurieren
$mail_method_used = configurePHPMailer($mail, $sender_name, $recipient_email);
// Empfänger
$mail->addAddress($recipient_email);
// Reply-To setzen, wenn Sender-Email verfügbar
if ($sender_email && filter_var($sender_email, FILTER_VALIDATE_EMAIL)) {
$mail->addReplyTo($sender_email);
}
// Anhänge
foreach ($uploaded_files as $file) {
if (file_exists($file["path"])) {
$mail->addAttachment($file["path"], $file["name"]);
}
}
// Inhalt
$mail->isHTML(true);
$mail->Subject = $subject;
$mail->Body = $mail_content_html;
$mail->AltBody = strip_tags($mail_content_text);
$mail->CharSet = "UTF-8";
$mail->Encoding = "base64";
// Mail senden mit Retry-Mechanismus
$max_retries = 2;
$retry_count = 0;
$sent = false;
while ($retry_count < $max_retries && !$sent) {
try {
$mail->send();
$sent = true;
$main_mail_sent = true;
} catch (Exception $e) {
$retry_count++;
if ($retry_count >= $max_retries) {
throw $e;
}
// Kurze Pause vor Wiederholung
sleep(1);
}
}
} catch (Exception $e) {
// Detaillierte Fehlerbehandlung
$error_message = "Fehler beim Senden der E-Mail";
// SMTP-spezifische Fehler
if (strpos($e->getMessage(), "SMTP") !== false) {
if (strpos($e->getMessage(), "Authentication") !== false) {
$error_message = "SMTP-Authentifizierung fehlgeschlagen. Bitte prüfen Sie Benutzername und Passwort.";
} elseif (strpos($e->getMessage(), "connect") !== false) {
$error_message = "Verbindung zum SMTP-Server fehlgeschlagen. Bitte prüfen Sie Host und Port.";
} elseif (strpos($e->getMessage(), "SSL") !== false || strpos($e->getMessage(), "TLS") !== false) {
$error_message = "SSL/TLS-Verschlüsselungsfehler. Bitte prüfen Sie die Verschlüsselungseinstellungen.";
} else {
$error_message = "SMTP-Fehler: " . $e->getMessage();
}
}
// Fehler protokollieren
error_log("Mail sending failed (Method: $mail_method_used): " . $e->getMessage());
http_response_code(500);
echo json_encode([
"success" => false,
"message" => $error_message
]);
exit;
}
// =============================================================
// KOPIE AN ABSENDER - VERBESSERTE VERSION
// =============================================================
if ($main_mail_sent && $send_copy_to_sender && !empty($sender_email)) {
// Kopie-E-Mail-Inhalt vorbereiten
$copy_subject = "Kopie Ihrer Nachricht: " . $subject;
$copy_body_html = "
<div style=\"font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto;\">
<h2 style=\"color: #333; border-bottom: 2px solid #007bff; padding-bottom: 10px;\">
Kopie Ihrer gesendeten Nachricht
</h2>
<p>Hallo,</p>
<p>vielen Dank für Ihre Nachricht. Hier ist eine Kopie der von Ihnen gesendeten Daten:</p>
<table style=\"border-collapse: collapse; width: 100%; border: 1px solid #ddd; margin: 20px 0;\">
<tbody>
";
$copy_body_text = "Kopie Ihrer gesendeten Nachricht:\n\n";
foreach ($_POST as $key => $value) {
if ($key === "captcha" || $key === "csrf_token" || $key === "name_hp" || $key === "send_copy_to_sender") continue;
$label = ucfirst(str_replace(["_", "-"], " ", $key));
if (is_array($value)) {
$value_str = implode(", ", array_map("htmlspecialchars", $value));
$value_text = implode(", ", $value);
} else {
$value_str = sanitize_input($value);
$value_text = $value;
}
$copy_body_html .= "
<tr>
<td style=\"padding: 12px; border: 1px solid #ddd; background-color: #f8f9fa; width: 30%; font-weight: bold; vertical-align: top;\">" . $label . "</td>
<td style=\"padding: 12px; border: 1px solid #ddd; vertical-align: top;\">" . nl2br($value_str) . "</td>
</tr>
";
$copy_body_text .= $label . ": " . $value_text . "\n";
}
$copy_body_html .= "
</tbody>
</table>
<p style=\"margin-top: 30px; color: #666; font-size: 0.9em; border-top: 1px solid #ddd; padding-top: 20px;\">
Diese E-Mail wurde automatisch generiert, da Sie eine Kopie Ihrer Nachricht angefordert haben.
</p>
</div>
";
// Kopie senden
try {
$copy_mail = new PHPMailer(true);
// Gleiche Konfiguration wie Hauptmail
configurePHPMailer($copy_mail, $sender_name, $recipient_email);
$copy_mail->addAddress($sender_email);
// Anhänge auch in Kopie
foreach ($uploaded_files as $file) {
if (file_exists($file["path"])) {
$copy_mail->addAttachment($file["path"], $file["name"]);
}
}
$copy_mail->isHTML(true);
$copy_mail->Subject = $copy_subject;
$copy_mail->Body = $copy_body_html;
$copy_mail->AltBody = strip_tags($copy_body_text);
$copy_mail->CharSet = "UTF-8";
$copy_mail->Encoding = "base64";
$copy_mail->send();
} catch (Exception $e) {
// Kopie-Fehler nur protokollieren, nicht kritisch
error_log("Copy Mail Error: " . $e->getMessage());
}
}
// =============================================================
// AUTOMATISCHE ANTWORT - VERBESSERTE VERSION
// =============================================================
if ($main_mail_sent && $enable_auto_reply && !empty($sender_email)) {
// Nachricht für automatische Antwort vorbereiten
$auto_reply_body_text = $auto_reply_message;
$auto_reply_body_html = nl2br(htmlspecialchars($auto_reply_message));
if ($auto_reply_include_original) {
$original_message = "\n\n" . str_repeat("-", 50) . "\nIhre ursprüngliche Nachricht:\n\n";
$original_html = "<hr style=\"margin: 30px 0;\"><h3>Ihre ursprüngliche Nachricht:</h3>";
foreach ($_POST as $key => $value) {
if ($key === "captcha" || $key === "csrf_token" || $key === "name_hp" || $key === "send_copy_to_sender") continue;
$label = ucfirst(str_replace(["_", "-"], " ", $key));
$value_display = is_array($value) ? implode(", ", $value) : $value;
$original_message .= $label . ": " . $value_display . "\n";
$original_html .= "<p><strong>" . htmlspecialchars($label) . ":</strong> " . htmlspecialchars($value_display) . "</p>";
}
$auto_reply_body_text .= $original_message;
$auto_reply_body_html .= $original_html;
}
// Automatische Antwort senden
try {
$auto_mail = new PHPMailer(true);
// Gleiche Konfiguration wie Hauptmail
configurePHPMailer($auto_mail, $auto_reply_sender_name, $recipient_email);
$auto_mail->addAddress($sender_email);
$auto_mail->isHTML($auto_reply_html_format);
$auto_mail->Subject = $auto_reply_subject;
$auto_mail->Body = $auto_reply_body_html;
$auto_mail->AltBody = strip_tags($auto_reply_body_text);
$auto_mail->CharSet = "UTF-8";
$auto_mail->Encoding = "base64";
$auto_mail->send();
} catch (Exception $e) {
// Auto-Reply-Fehler nur protokollieren
error_log("Auto-Reply Error: " . $e->getMessage());
}
}
// CAPTCHA-Session nach erfolgreichem Absenden löschen
unset($_SESSION["captcha_code"]);
// Erfolgs-Antwort an JavaScript zurückgeben
echo json_encode(["success" => true, "message" => $success_message]);
exit;
} else {
// Direkter Aufruf der send.php blockieren
http_response_code(403);
echo json_encode(["success" => false, "message" => "Direkter Zugriff nicht erlaubt."]);
exit;
}
?>