Files
api/services/nginx/app/classes/email.php
T
Jepp9350 6efa414251 Refactor SMS and notification logic; add email template.
Updated the SMS sending logic to improve validation and handling of recipients in `gatewayapi.php`. Refactored notification conditions in `bookings_o.php` to ensure proper fallback mechanisms. Additionally, included a new booking notification email template in `email.php`.
2025-04-14 09:58:25 +02:00

331 lines
12 KiB
PHP

<?php
namespace classes;
require_once WD . '/modules/email/email_c.php';
require_once WD . '/modules/email/helpers/email_template.php';
require_once WD . '/modules/email/templates/email_template_header.php';
require_once WD . '/modules/email/templates/email_template_footer.php';
require_once WD . '/modules/email/templates/email_template_head.php';
require_once WD . '/modules/email/templates/email_template_stripe_invoice.php';
require_once WD . '/modules/email/templates/email_template_booking_confirmation.php';
require_once WD . '/modules/email/templates/email_template_booking_notification.php';
require_once WD . '/modules/email/templates/email_template_wash_certificate.php';
use email\email_c;
use email\templates\email_template_booking_confirmation;
use email\templates\email_template_booking_notification;
use email\templates\email_template_footer;
use email\templates\email_template_head;
use email\templates\email_template_header;
use email\templates\email_template_stripe_invoice;
use email\templates\email_template_wash_certificate;
use Exception;
use interfaces\email_i;
use JsonException;
use MailerSend\Exceptions\MailerSendAssertException;
use MailerSend\Exceptions\MailerSendException;
use MailerSend\Helpers\Builder\Attachment;
use MailerSend\Helpers\Builder\EmailParams;
use MailerSend\Helpers\Builder\Header;
use MailerSend\Helpers\Builder\Recipient;
use MailerSend\MailerSend;
use objects\bookings_o;
use objects\departments_o;
use objects\users_o;
use Psr\Http\Client\ClientExceptionInterface;
class email implements email_i
{
/**
* Configuration for the email service
* @var email_c
*/
public email_c $config;
public function __construct()
{
$this->config = new email_c();
}
public function testConfigRequest(string $test_recipient): string
{
if ($test_recipient) {
try {
$this->sendEmail($test_recipient, 'Test recipient', 'Test email', 'This is a test email');
return 'Email sent successfully to ' . $test_recipient;
} catch (Exception $e) {
return 'Email error: ' . $e->getMessage();
}
} else {
return 'No test recipient provided';
}
}
/**
* Send an email using the preferred email service
* @param string $to Email address to send the email to
* @param string $recipient_name Name of the recipient
* @param string $subject Subject of the email
* @param string $message Message of the email
* @throws Exception If an error occurs while sending the email
*/
public function sendEmail(string $to, string $recipient_name, string $subject, string $message, string $references = null): void
{
if ($this->config->mailersend_enabled->getVariableValue()) {
try {
// Generate HTML email
$html = self::generateHtmlHeader();
// Add email content
$html .= $message;
// Add email footer
$html .= self::generateHtmlFooter();
$this->sendEmailMailerSend($to, $recipient_name, $subject, $message, $html, $references);
} catch (JsonException|MailerSendException|ClientExceptionInterface $e) {
throw new Exception('Error sending email: ' . $e->getMessage());
}
} else {
$this->sendEmailDefault($to, $subject, $message);
}
}
private static function generateHtmlHeader(): false|string
{
$email_template_head = (new email_template_head())->generate_html();
$email_template_header = (new email_template_header())->generate_html();
return "
<!DOCTYPE html>
<html lang='da'>
<head>
$email_template_head
</head>
<body>
$email_template_header";
}
private static function generateHtmlFooter(): string
{
$email_template_footer = (new email_template_footer())->generate_html();
return "
$email_template_footer
</body>
</html>";
}
/**
* @throws ClientExceptionInterface
* @throws JsonException
* @throws MailerSendAssertException
* @throws MailerSendException
*/
private function sendEmailMailerSend(string $to, string $recipient_name, string $subject, string $message, string $html = null, string $references = null, array $attachments = []): void
{
// Send POST request to email service
$mailersend = new MailerSend(['api_key' => $this->config->mailersend_api_key->getVariableValue()]);
$recipients = [
new Recipient($to, $recipient_name)
];
$emailParams = (new EmailParams())
->setFrom($this->config->smtp_from->getVariableValue())
->setFromName($this->config->smtp_from_name->getVariableValue())
->setRecipients($recipients)
->setSubject($subject)
->setHtml($html ?? $message)
->setReplyTo($this->config->smtp_reply_to->getVariableValue())
->setReplyToName($this->config->smtp_reply_to_name->getVariableValue());
if ($attachments) {
$attachments = array_map(function ($attachment) {
// Read the data from the path (Attachment[0]) and set the filename (Attachment[1])
$attachment[0] = file_get_contents($attachment[0]);
if ($attachment[0] === false) {
throw new Exception('Failed to read file: ' . $attachment[0]);
}
if (empty($attachment[1])) {
throw new Exception('Filename is empty');
}
return new Attachment($attachment[0], $attachment[1]);
}, $attachments);
}
if ($attachments) {
$emailParams->setAttachments($attachments);
}
if ($references) {
$emailParams->setHeaders([
new Header('References', $references)
]);
}
$mailersend->email->send($emailParams);
}
/**
* Send an email using the default SMTP service
* @param string $to Email address to send the email to
* @param string $subject Subject of the email
* @param string $message Message of the email
* @throws Exception If an error occurs while sending the email
*/
private function sendEmailDefault(string $to, string $subject, string $message): void
{
// Send email using default SMTP service
throw new Exception('Default SMTP service not implemented');
}
/**
* @throws MailerSendException
* @throws ClientExceptionInterface
* @throws JsonException
* @throws MailerSendAssertException
*/
public function sendStripeInvoiceEmail(string $to, string|null $recipient_name, string $payment_link, $order_id): void
{
$recipient_name = $recipient_name ?? 'Kunde';
$recipient_name = ucfirst($recipient_name);
// Generate HTML email
$html = self::generateHtmlHeader();
// Add email content
$html .= (new email_template_stripe_invoice(
$order_id,
$payment_link,
$recipient_name
))->generate_html();
// Add email footer
$html .= self::generateHtmlFooter();
$this->sendEmailMailerSend($to, $recipient_name, 'Betalingslink for bestilling #' . $order_id, '', $html);
}
/**
* Send a booking confirmation email
* @throws MailerSendException
* @throws ClientExceptionInterface
* @throws JsonException
* @throws MailerSendAssertException
* @throws Exception
*/
public function sendBookingConfirmationEmail(
int $booking_id,
): void
{
// Get the booking details from the database
$booking = (new bookings_o())->select((int)$booking_id);
$customer = (new users_o())->getUserByCustomerNumber((int)$booking->customer_number->value());
$department = (new departments_o())->select((int)$booking->department->value());
// Generate HTML email
$html = self::generateHtmlHeader();
// Add email content
$html .= (new email_template_booking_confirmation(
$booking->id,
$customer->getCustomerName((int)$customer->customer_number->value()),
$customer->customer_number->value(),
$booking->contact_email->value(),
$booking->reference_number->value(),
$booking->regNrTraekker->value(),
$booking->regNrTrailer->value(),
($booking->washCertificateStatus->value() === 'cancelled' ? 'Nej' : 'Ja'),
(!empty($booking->washCertificateEmail->value()) ? (string)$booking->washCertificateEmail->value() : ''),
$booking->date->value(),
(string)$department->getDepartmentName((int)$department->id),
(string)$department->getBranding()->address->value(),
$booking->pickup_bool->value() === 'yes' ? 'Ja' : 'Nej',
$booking->notes->value(),
))->generate_html();
// Add email footer
$html .= self::generateHtmlFooter();
// Send email
$this->sendEmailMailerSend(
$booking->contact_email->value(),
$customer->getCustomerName((int)$customer->customer_number->value()),
'Truck Wash Booking ( ID: ' . $booking_id . ', REF: ' . $booking->reference_number->value() . ' )',
'',
$html
);
}
/**
* Send a wash certificate email
* @throws MailerSendException
* @throws ClientExceptionInterface
* @throws JsonException
* @throws MailerSendAssertException
*/
public function sendWashCertificateEmail(
$booking_id,
$company_name,
$contact_email,
$reference_number,
$wash_certificate_url,
$wash_certificate_email,
): void
{
// Generate HTML email
$html = self::generateHtmlHeader();
// Add email content
$html .= (new email_template_wash_certificate(
$booking_id,
$company_name,
))->generate_html();
// Add email footer
$html .= self::generateHtmlFooter();
// Attach the wash certificate
$pdf = (new pdf_store())->download($wash_certificate_url);
// Send email
$this->sendEmailMailerSend(
$wash_certificate_email,
$company_name,
'Truck Wash Booking ( ID: ' . $booking_id . ', REF: ' . $reference_number . ' )',
'',
$html,
null,
[
[
$pdf,
'wash_certificate_' . $booking_id . '_' . $reference_number . '.pdf'
]
]
);
}
/**
* @throws Exception
* @throws ClientExceptionInterface
*/
public function sendBookingNotification(int $booking_id): void
{
// Get the booking details from the database
$booking = (new bookings_o())->select((int)$booking_id);
$customer = (new users_o())->getUserByCustomerNumber((int)$booking->customer_number->value());
$department = (new departments_o())->select((int)$booking->department->value());
// Generate HTML email
$html = self::generateHtmlHeader();
$html .= (new email_template_booking_notification(
$booking->id,
$customer->getCustomerName((int)$customer->customer_number->value()),
$customer->customer_number->value(),
$booking->contact_email->value(),
$booking->reference_number->value(),
$booking->regNrTraekker->value(),
$booking->regNrTrailer->value(),
($booking->washCertificateStatus->value() === 'cancelled' ? 'Nej' : 'Ja'),
(!empty($booking->washCertificateEmail->value()) ? (string)$booking->washCertificateEmail->value() : ''),
$booking->date->value(),
(string)$department->getDepartmentName((int)$department->id),
(string)$department->getBranding()->address->value(),
$booking->pickup_bool->value() === 'yes' ? 'Ja' : 'Nej',
$booking->notes->value(),
))->generate_html();
// Add email footer
$html .= self::generateHtmlFooter();
// Send email
$this->sendEmailMailerSend(
$department->getBranding()->email->value(),
$department->getDepartmentName((int)$department->id),
'Truck Wash Booking ( ID: ' . $booking_id . ', REF: ' . $booking->reference_number->value() . ' )',
'',
$html
);
}
}