formatOutput = true; $root = $xml->createElement('form_submission'); $xml->appendChild($root); // Static data $static = $xml->createElement('static'); $root->appendChild($static); foreach (['name', 'lastname', 'title', 'telno', 'mail', 'apparatsname', 'subject', 'semester', 'dauerapparat'] as $field) { if (isset($data[$field])) { $element = $xml->createElement($field, htmlspecialchars($data[$field])); $static->appendChild($element); } } if (!empty($data['message'])) { $messageEl = $xml->createElement('message', htmlspecialchars($data['message'])); $static->appendChild($messageEl); } // Books if (isset($data['books']) && is_array($data['books'])) { $booksNode = $xml->createElement('books'); $root->appendChild($booksNode); foreach ($data['books'] as $book) { $bookNode = $xml->createElement('book'); $booksNode->appendChild($bookNode); foreach (['authorname', 'year', 'title', 'signature'] as $field) { $value = isset($book[$field]) ? htmlspecialchars($book[$field]) : ''; $fieldNode = $xml->createElement($field, $value); $bookNode->appendChild($fieldNode); } } } return $xml->saveXML(); } /** * Generate XML for ELSA form */ function generateELSAXML($data) { $xml = new DOMDocument('1.0', 'UTF-8'); $xml->formatOutput = true; $root = $xml->createElement('elsa_submission'); $xml->appendChild($root); // General info $generalInfo = $xml->createElement('general_info'); $root->appendChild($generalInfo); $generalFields = [ 'name', 'lastname', 'title', 'mail', 'subject', 'classname', 'usage_date_from', 'usage_date_to', 'availability_date' ]; foreach ($generalFields as $field) { if (isset($data[$field])) { $element = $xml->createElement($field, htmlspecialchars($data[$field])); $generalInfo->appendChild($element); } } if (!empty($data['message'])) { $messageEl = $xml->createElement('message', htmlspecialchars($data['message'])); $generalInfo->appendChild($messageEl); } // Media sections $mediaRoot = $xml->createElement('media'); $root->appendChild($mediaRoot); // Add different media types (monografie, zeitschrift, herausgeber) $mediaTypes = [ 'monografien' => $data['monografien'] ?? [], 'zeitschriftenartikel' => $data['zeitschriftenartikel'] ?? [], 'herausgeberwerke' => $data['herausgeberwerke'] ?? [] ]; foreach ($mediaTypes as $type => $entries) { if (!empty($entries)) { $section = $xml->createElement($type); $mediaRoot->appendChild($section); foreach ($entries as $entry) { $entryNode = $xml->createElement('entry'); $section->appendChild($entryNode); foreach ($entry as $key => $value) { $fieldNode = $xml->createElement($key, htmlspecialchars($value)); $entryNode->appendChild($fieldNode); } } } } return $xml->saveXML(); } /** * Send email with XML attachment * Uses PHP's mail() function or SMTP if configured */ function sendEmail($subject, $xmlContent, $toEmail = null) { $to = $toEmail ?? MAIL_TO; $from = MAIL_FROM; writeLog("=========================================================="); writeLog("Email Send Attempt"); writeLog("From: {$from}"); writeLog("To: {$to}"); writeLog("Subject: {$subject}"); writeLog("Content Length: " . strlen($xmlContent) . " bytes"); if (!MAIL_ENABLED) { writeLog("MAIL SENDING DISABLED - Email not sent", 'WARNING'); writeLog("XML Content:\n" . $xmlContent); writeLog("=========================================================="); return true; } // Try using SMTP if credentials are configured if (SMTP_USERNAME && SMTP_PASSWORD) { writeLog("SMTP credentials configured, attempting SMTP send"); $result = sendEmailSMTP($subject, $xmlContent, $to, $from); if ($result) { writeLog("Email sent successfully via SMTP", 'SUCCESS'); } else { writeLog("Email sending via SMTP failed", 'ERROR'); } writeLog("=========================================================="); return $result; } // Fallback to PHP mail() only if no SMTP credentials writeLog("No SMTP credentials configured, using PHP mail() function"); $headers = "From: " . $from . "\r\n"; $headers .= "Content-Type: application/xml; charset=UTF-8\r\n"; $headers .= "X-Mailer: PHP/" . phpversion(); $result = mail($to, $subject, $xmlContent, $headers); if ($result) { writeLog("Email sent successfully via mail()", 'SUCCESS'); } else { writeLog("Email sending via mail() failed", 'ERROR'); } writeLog("=========================================================="); return $result; } /** * Send email via SMTP using PHPMailer (if available) or native PHP sockets */ function sendEmailSMTP($subject, $xmlContent, $to, $from) { // Try PHPMailer first if available if (class_exists('PHPMailer\PHPMailer\PHPMailer')) { writeLog("Initializing PHPMailer for SMTP send"); writeLog("SMTP Host: " . SMTP_HOST . ":" . SMTP_PORT); writeLog("SMTP Encryption: " . SMTP_ENCRYPTION); writeLog("SMTP Username: " . SMTP_USERNAME); $mail = new PHPMailer\PHPMailer\PHPMailer(true); try { // Server settings $mail->isSMTP(); $mail->Host = SMTP_HOST; $mail->SMTPAuth = true; $mail->Username = SMTP_USERNAME; $mail->Password = SMTP_PASSWORD; $mail->SMTPSecure = SMTP_ENCRYPTION; $mail->Port = SMTP_PORT; $mail->CharSet = 'UTF-8'; writeLog("SMTP connection configured"); // Recipients $mail->setFrom($from); $mail->addAddress($to); writeLog("Recipients configured"); // Content - XML as body $mail->isHTML(false); $mail->Subject = $subject; $mail->Body = $xmlContent; $mail->ContentType = 'text/plain'; writeLog("Sending email via SMTP..."); $mail->send(); writeLog("SMTP send() completed successfully", 'SUCCESS'); return true; } catch (Exception $e) { writeLog("SMTP Exception: " . $e->getMessage(), 'ERROR'); writeLog("PHPMailer ErrorInfo: " . $mail->ErrorInfo, 'ERROR'); return false; } } // Helper function to read SMTP multi-line response $readResponse = function ($socket) { $response = ''; while ($line = fgets($socket, 515)) { $response .= $line; // Check if this is the last line (code followed by space, not hyphen) if (preg_match('/^\d{3} /', $line)) { break; } } return $response; }; // Fallback to native PHP SMTP writeLog("PHPMailer not available, using native PHP SMTP implementation"); writeLog("SMTP Host: " . SMTP_HOST . ":" . SMTP_PORT); writeLog("SMTP Encryption: " . SMTP_ENCRYPTION); // Check if required transports are available $transports = stream_get_transports(); writeLog("Available transports: " . implode(', ', $transports)); if (SMTP_ENCRYPTION === 'ssl' && !in_array('ssl', $transports)) { writeLog("SSL transport not available. Enable OpenSSL extension in PHP.", 'ERROR'); writeLog("Try changing SMTP_ENCRYPTION to 'tls' and SMTP_PORT to 587 in config.php", 'ERROR'); return false; } try { // Build the connection string - always start with plain TCP for TLS if (SMTP_ENCRYPTION === 'ssl') { $host = 'ssl://' . SMTP_HOST; } else { $host = SMTP_HOST; } $timeout = 30; writeLog("Connecting to {$host}:" . SMTP_PORT); $smtp = @fsockopen($host, SMTP_PORT, $errno, $errstr, $timeout); if (!$smtp) { writeLog("Failed to connect: ({$errno}) {$errstr}", 'ERROR'); return false; } writeLog("Connected successfully"); // Read server response $response = $readResponse($smtp); writeLog("Server greeting: " . trim($response)); // Send EHLO fputs($smtp, "EHLO " . SMTP_HOST . "\r\n"); $response = $readResponse($smtp); writeLog("EHLO response: " . trim(str_replace("\r\n", " | ", $response))); // Start TLS if needed and not using SSL if (SMTP_ENCRYPTION === 'tls') { fputs($smtp, "STARTTLS\r\n"); $response = $readResponse($smtp); writeLog("STARTTLS response: " . trim($response)); if (strpos($response, '220') === 0) { if (in_array('tls', $transports) || in_array('ssl', $transports)) { $crypto = @stream_socket_enable_crypto($smtp, true, STREAM_CRYPTO_METHOD_TLS_CLIENT); if ($crypto) { writeLog("TLS encryption enabled successfully"); fputs($smtp, "EHLO " . SMTP_HOST . "\r\n"); $response = $readResponse($smtp); writeLog("EHLO after TLS: " . trim(str_replace("\r\n", " | ", $response))); } else { writeLog("Failed to enable TLS encryption", 'WARNING'); writeLog("Continuing without encryption (not recommended)", 'WARNING'); } } else { writeLog("TLS/SSL transports not available. Enable OpenSSL extension.", 'WARNING'); writeLog("Continuing without encryption (not recommended)", 'WARNING'); } } } // Authenticate fputs($smtp, "AUTH LOGIN\r\n"); $response = $readResponse($smtp); writeLog("AUTH response: " . trim($response)); fputs($smtp, base64_encode(SMTP_USERNAME) . "\r\n"); $response = $readResponse($smtp); fputs($smtp, base64_encode(SMTP_PASSWORD) . "\r\n"); $response = $readResponse($smtp); if (strpos($response, '235') !== 0) { writeLog("Authentication failed: " . trim($response), 'ERROR'); fclose($smtp); return false; } writeLog("Authentication successful"); // Send MAIL FROM fputs($smtp, "MAIL FROM: <{$from}>\r\n"); $response = $readResponse($smtp); writeLog("MAIL FROM response: " . trim($response)); // Send RCPT TO fputs($smtp, "RCPT TO: <{$to}>\r\n"); $response = $readResponse($smtp); writeLog("RCPT TO response: " . trim($response)); // Send DATA fputs($smtp, "DATA\r\n"); $response = $readResponse($smtp); writeLog("DATA response: " . trim($response)); // Send email headers and body $headers = "From: {$from}\r\n"; $headers .= "To: {$to}\r\n"; $headers .= "Subject: {$subject}\r\n"; $headers .= "Content-Type: text/plain; charset=UTF-8\r\n"; $headers .= "X-Mailer: PHP/" . phpversion() . "\r\n"; $headers .= "\r\n"; fputs($smtp, $headers . $xmlContent . "\r\n.\r\n"); $response = $readResponse($smtp); writeLog("Message response: " . trim($response)); // Quit fputs($smtp, "QUIT\r\n"); $readResponse($smtp); // Read QUIT response fclose($smtp); if (strpos($response, '250') === 0) { writeLog("Email sent successfully via native SMTP", 'SUCCESS'); return true; } else { writeLog("Email sending failed: " . trim($response), 'ERROR'); return false; } } catch (Exception $e) { writeLog("Native SMTP Exception: " . $e->getMessage(), 'ERROR'); return false; } } /** * Redirect to URL */ function redirect($url) { header("Location: " . $url); exit; } /** * Get POST value with default */ function post($key, $default = '') { return isset($_POST[$key]) ? sanitizeInput($_POST[$key]) : $default; } /** * Get all POST values matching a pattern (for arrays) */ function postArray($key) { return isset($_POST[$key]) && is_array($_POST[$key]) ? array_map('sanitizeInput', $_POST[$key]) : []; }