Files
PHPSemapForm/functions.php
2025-12-09 10:07:14 +01:00

436 lines
13 KiB
PHP

<?php
require_once 'config.php';
/**
* Write log message to file
*/
function writeLog($message, $level = 'INFO')
{
if (!LOG_ENABLED) {
return;
}
$timestamp = date('Y-m-d H:i:s');
$logMessage = "[{$timestamp}] [{$level}] {$message}" . PHP_EOL;
// Also log to error_log for immediate visibility
error_log("[MAIL] {$message}");
// Write to log file
if (defined('LOG_FILE')) {
file_put_contents(LOG_FILE, $logMessage, FILE_APPEND | LOCK_EX);
}
}
/**
* Validate email address
*/
function validateEmail($email)
{
return preg_match(EMAIL_REGEX, $email);
}
/**
* Sanitize input string
*/
function sanitizeInput($input)
{
return htmlspecialchars(trim($input), ENT_QUOTES, 'UTF-8');
}
/**
* Generate XML from form data
*/
function generateXML($data)
{
$xml = new DOMDocument('1.0', 'UTF-8');
$xml->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]) : [];
}