feat: implement email logging and test price mode functionality with QR code generation for order confirmations

This commit is contained in:
2026-03-10 13:20:22 +01:00
parent 61e480cc94
commit 752b6c653e
8 changed files with 412 additions and 36 deletions

View File

@@ -1,6 +1,78 @@
<?php
class S
{
private static function get_route_param( $var )
{
$var = trim((string) $var);
if ( $var === '' || empty($_SERVER['REQUEST_URI']) )
return null;
$uriPath = explode('?', (string) $_SERVER['REQUEST_URI'], 2)[0];
$segments = explode('/', trim($uriPath, '/'));
foreach ( $segments as $segment )
{
if ( strpos($segment, '=') === false )
continue;
list($key, $value) = explode('=', $segment, 2);
if ( trim((string) $key) === $var )
return urldecode((string) $value);
}
return null;
}
private static function get_rewrite_tail_param( $var )
{
$var = trim((string) $var);
$queryString = (string) ( $_SERVER['QUERY_STRING'] ?? '' );
if ( $var === '' || $queryString === '' )
return null;
$parts = explode('/', $queryString);
foreach ( $parts as $part )
{
if ( strpos($part, '=') === false )
continue;
list($key, $value) = explode('=', $part, 2);
if ( trim((string) $key) === $var )
return urldecode((string) $value);
}
return null;
}
private static function log_mail_event( $level, $message, $context = [] )
{
global $settings;
if ( empty($settings['mail_debug_log_enabled']) )
return;
$rootPath = dirname(__DIR__);
$logFile = $rootPath . DIRECTORY_SEPARATOR . 'mail_debug.log';
$time = date('Y-m-d H:i:s');
$line = '[' . $time . '] [' . strtoupper((string) $level) . '] ' . (string) $message;
if ( is_array( $context ) && !empty( $context ) )
{
$line .= ' | ' . json_encode( $context, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES );
}
$line .= PHP_EOL;
$written = @file_put_contents( $logFile, $line, FILE_APPEND );
if ( $written === false )
{
if ( !empty($settings['mail_debug_error_log_enabled']) )
error_log( 'Mail log write error: ' . $logFile . ' | ' . $line );
}
}
public static function array_unique_multi( $array, $key )
{
$temp_array = [];
@@ -172,8 +244,31 @@ class S
}
if ( isset( $_GET[ $var ] ) )
{
return $_GET[ $var ];
$value = $_GET[ $var ];
if ( is_string($value) && strpos($value, '/') !== false )
{
$segments = explode('/', $value);
$head = trim((string) ($segments[0] ?? ''));
if ( $head !== '' )
return urldecode($head);
}
return $value;
}
$routeValue = self::get_route_param( $var );
if ( $routeValue !== null )
{
return $routeValue;
}
$rewriteTailValue = self::get_rewrite_tail_param( $var );
if ( $rewriteTailValue !== null )
{
return $rewriteTailValue;
}
return null;
}
@@ -198,10 +293,94 @@ class S
return filter_var( $email, FILTER_VALIDATE_EMAIL );
}
private static function normalize_attachments( $file )
{
$attachments = [];
if ( is_array( $file ) )
{
foreach ( $file as $file_tmp )
{
if ( !empty( $file_tmp ) && file_exists( $file_tmp ) )
$attachments[] = $file_tmp;
}
}
else
{
if ( !empty( $file ) && file_exists( $file ) )
$attachments[] = $file;
}
return $attachments;
}
private static function send_email_native( $email, $subject, $text, $attachments, $settings )
{
$from = trim((string) ($settings['email_from'] ?? 'bilety@brzezovka.pl'));
$replyTo = trim((string) ($settings['email_reply_to'] ?? $from));
$bccEmail = trim((string) ($settings['email_bcc'] ?? ''));
$headers = [];
$headers[] = 'From: ' . $from;
$headers[] = 'Reply-To: ' . $replyTo;
if ( $bccEmail !== '' && self::email_check( $bccEmail ) )
$headers[] = 'Bcc: ' . $bccEmail;
$headers[] = 'MIME-Version: 1.0';
$encodedSubject = '=?UTF-8?B?' . base64_encode((string) $subject) . '?=';
if ( empty($attachments) )
{
$headers[] = 'Content-Type: text/html; charset=UTF-8';
$ok = @mail($email, $encodedSubject, (string) $text, implode("\r\n", $headers));
return (bool) $ok;
}
$boundary = 'boundary_' . md5(uniqid((string) mt_rand(), true));
$headers[] = 'Content-Type: multipart/mixed; boundary="' . $boundary . '"';
$body = '';
$body .= '--' . $boundary . "\r\n";
$body .= "Content-Type: text/html; charset=UTF-8\r\n";
$body .= "Content-Transfer-Encoding: 8bit\r\n\r\n";
$body .= (string) $text . "\r\n";
foreach ( $attachments as $attachment )
{
$content = @file_get_contents($attachment);
if ( $content === false )
continue;
$filename = basename($attachment);
$body .= '--' . $boundary . "\r\n";
$body .= 'Content-Type: application/octet-stream; name="' . $filename . '"' . "\r\n";
$body .= "Content-Transfer-Encoding: base64\r\n";
$body .= 'Content-Disposition: attachment; filename="' . $filename . '"' . "\r\n\r\n";
$body .= chunk_split(base64_encode($content)) . "\r\n";
}
$body .= '--' . $boundary . "--\r\n";
$ok = @mail($email, $encodedSubject, $body, implode("\r\n", $headers));
return (bool) $ok;
}
public static function send_email( $email, $subject, $text, $file = '' )
{
global $settings;
$email = trim((string) $email);
if ( !self::email_check( $email ) )
{
self::log_mail_event( 'error', 'Mail send aborted - invalid recipient', [
'to' => $email,
'subject' => $subject
] );
return false;
}
$attachments = self::normalize_attachments( $file );
$mail = new PHPMailer;
$mail -> IsSMTP();
$mail -> SMTPAuth = true;
@@ -220,27 +399,65 @@ class S
$mail -> From = 'bilety@brzezovka.pl';
$mail -> FromName = 'KOMPLEKS TURYSTYCZNY BRZEZÓVKA';
$mail -> addAddress( $email, $email );
$mail -> addBCC( 'bilety@brzezovka.pl' );
$mail -> addReplyTo( 'bilety@brzezovka.pl', 'KOMPLEKS TURYSTYCZNY BRZEZÓVKA' );
$mail -> isHTML( true );
$bccEmail = trim((string) ($settings['email_bcc'] ?? ''));
if ( $bccEmail !== '' && self::email_check( $bccEmail ) )
{
$mail -> addBCC( $bccEmail );
}
$mail -> Subject = $subject;
$mail -> Body = $text;
foreach ( $attachments as $attachment )
$mail -> AddAttachment( $attachment );
if ( is_array( $file ) )
{
foreach ( $file as $file_tmp )
self::log_mail_event( 'info', 'Mail send attempt', [
'to' => $email,
'subject' => $subject,
'attachments' => $attachments
] );
$isSent = $mail -> send();
if (!$isSent) {
self::log_mail_event( 'error', 'Mail send failed', [
'to' => $email,
'subject' => $subject,
'error' => $mail->ErrorInfo
] );
if ( !empty($settings['mail_debug_error_log_enabled']) )
error_log('Mail send error to ' . $email . ': ' . $mail->ErrorInfo);
self::log_mail_event( 'info', 'Mail send fallback attempt (native mail)', [
'to' => $email,
'subject' => $subject
] );
$fallbackSent = self::send_email_native( $email, $subject, $text, $attachments, $settings );
if ( $fallbackSent )
{
if ( !empty( $file_tmp ) && file_exists( $file_tmp ) )
$mail -> AddAttachment( $file_tmp );
self::log_mail_event( 'info', 'Mail send fallback success (native mail)', [
'to' => $email,
'subject' => $subject
] );
return true;
}
}
else
{
if ( !empty( $file ) && file_exists( $file ) )
$mail -> AddAttachment( $file );
$lastError = error_get_last();
self::log_mail_event( 'error', 'Mail send fallback failed (native mail)', [
'to' => $email,
'subject' => $subject,
'error' => is_array($lastError) ? ($lastError['message'] ?? '') : ''
] );
} else {
self::log_mail_event( 'info', 'Mail send success', [
'to' => $email,
'subject' => $subject
] );
}
return $mail -> send();
return $isSent;
}
}