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 " $email_template_head $email_template_header"; } private static function generateHtmlFooter(): string { $email_template_footer = (new email_template_footer())->generate_html(); return " $email_template_footer "; } /** * @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 { // Check if the email is blacklisted $blacklisted_emails = [ 'invoice.dk@freja.com', // TODO: Make this dynamic. ]; // If the email is blacklisted, return without sending the email if (in_array($to, $blacklisted_emails)) { return; } // 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 ); } }