diff --git a/api/app/Notifications/Forms/FormEmailNotification.php b/api/app/Notifications/Forms/FormEmailNotification.php index da127de6..793f379a 100644 --- a/api/app/Notifications/Forms/FormEmailNotification.php +++ b/api/app/Notifications/Forms/FormEmailNotification.php @@ -19,7 +19,6 @@ class FormEmailNotification extends Notification implements ShouldQueue public FormSubmitted $event; public string $mailer; - private array $formattedData; /** * Create a new notification instance. @@ -30,7 +29,6 @@ public function __construct(FormSubmitted $event, private $integrationData, stri { $this->event = $event; $this->mailer = $mailer; - $this->formattedData = $this->formatSubmissionData(); } /** @@ -54,7 +52,7 @@ public function toMail($notifiable) { return (new MailMessage()) ->mailer($this->mailer) - ->replyTo($this->getReplyToEmail($notifiable->routes['mail'])) + ->replyTo($this->getReplyToEmail($this->event->form->creator->email)) ->from($this->getFromEmail(), $this->getSenderName()) ->subject($this->getSubject()) ->withSymfonyMessage(function (Email $message) { @@ -63,13 +61,15 @@ public function toMail($notifiable) ->markdown('mail.form.email-notification', $this->getMailData()); } - private function formatSubmissionData(): array + private function formatSubmissionData($createLinks = true): array { $formatter = (new FormSubmissionFormatter($this->event->form, $this->event->data)) - ->createLinks() ->outputStringsOnly() ->useSignedUrlForFiles(); + if ($createLinks) { + $formatter->createLinks(); + } if ($this->integrationData->include_hidden_fields_submission_data ?? false) { $formatter->showHiddenFields(); } @@ -98,27 +98,25 @@ private function getSenderName(): string private function getReplyToEmail($default): string { $replyTo = $this->integrationData->reply_to ?? null; - if ($replyTo) { $parsedReplyTo = $this->parseReplyTo($replyTo); if ($parsedReplyTo && $this->validateEmail($parsedReplyTo)) { return $parsedReplyTo; } } - - return $this->getRespondentEmail() ?? $default; + return $default; } private function parseReplyTo(string $replyTo): ?string { - $parser = new MentionParser($replyTo, $this->formattedData); + $parser = new MentionParser($replyTo, $this->formatSubmissionData(false)); return $parser->parse(); } private function getSubject(): string { $defaultSubject = 'New form submission'; - $parser = new MentionParser($this->integrationData->subject ?? $defaultSubject, $this->formattedData); + $parser = new MentionParser($this->integrationData->subject ?? $defaultSubject, $this->formatSubmissionData(false)); return $parser->parse(); } @@ -150,7 +148,7 @@ private function getMailData(): array { return [ 'emailContent' => $this->getEmailContent(), - 'fields' => $this->formattedData, + 'fields' => $this->formatSubmissionData(), 'form' => $this->event->form, 'integrationData' => $this->integrationData, 'noBranding' => $this->event->form->no_branding, @@ -160,7 +158,7 @@ private function getMailData(): array private function getEmailContent(): string { - $parser = new MentionParser($this->integrationData->email_content ?? '', $this->formattedData); + $parser = new MentionParser($this->integrationData->email_content ?? '', $this->formatSubmissionData()); return $parser->parse(); } @@ -170,26 +168,6 @@ private function getEncodedSubmissionId(): ?string return $submissionId ? Hashids::encode($submissionId) : null; } - private function getRespondentEmail(): ?string - { - $emailFields = ['email', 'e-mail', 'mail']; - - foreach ($this->formattedData as $field => $value) { - if (in_array(strtolower($field), $emailFields) && $this->validateEmail($value)) { - return $value; - } - } - - // If no email field found, search for any field containing a valid email - foreach ($this->formattedData as $value) { - if ($this->validateEmail($value)) { - return $value; - } - } - - return null; - } - public static function validateEmail($email): bool { return (bool)filter_var($email, FILTER_VALIDATE_EMAIL); diff --git a/api/tests/Feature/Forms/EmailNotificationTest.php b/api/tests/Feature/Forms/EmailNotificationTest.php index 03cf5acf..85073609 100644 --- a/api/tests/Feature/Forms/EmailNotificationTest.php +++ b/api/tests/Feature/Forms/EmailNotificationTest.php @@ -26,6 +26,7 @@ $notifiable->route('mail', 'test@test.com'); $renderedMail = $mailable->toMail($notifiable); expect($renderedMail->subject)->toBe('New form submission'); + expect($renderedMail->replyTo[0][0])->toBe('reply@example.com'); expect(trim($renderedMail->render()))->toContain('Test body'); }); @@ -163,3 +164,65 @@ function (FormEmailNotification $notification, $channels, $notifiable) { expect($renderedMail->subject)->toBe('Custom Subject'); expect(trim($renderedMail->render()))->toContain('Custom content'); }); + +it('send email with mention as reply to', function () { + $user = $this->actingAsUser(); + $workspace = $this->createUserWorkspace($user); + $form = $this->createForm($user, $workspace); + + $emailProperty = collect($form->properties)->first(function ($property) { + return $property['type'] == 'email'; + }); + + $integrationData = $this->createFormIntegration('email', $form->id, [ + 'send_to' => 'test@test.com', + 'sender_name' => 'OpnForm', + 'subject' => 'New form submission', + 'email_content' => 'Hello there 👋
Test body', + 'include_submission_data' => true, + 'include_hidden_fields_submission_data' => false, + 'reply_to' => '' . $emailProperty['name'] . '' + ]); + + $formData = [ + $emailProperty['id'] => 'reply@example.com', + ]; + + $event = new \App\Events\Forms\FormSubmitted($form, $formData); + $mailable = new FormEmailNotification($event, $integrationData, 'mail'); + $notifiable = new AnonymousNotifiable(); + $notifiable->route('mail', 'test@test.com'); + $renderedMail = $mailable->toMail($notifiable); + expect($renderedMail->replyTo[0][0])->toBe('reply@example.com'); +}); + +it('send email with empty reply to', function () { + $user = $this->actingAsUser(); + $workspace = $this->createUserWorkspace($user); + $form = $this->createForm($user, $workspace); + + $emailProperty = collect($form->properties)->first(function ($property) { + return $property['type'] == 'email'; + }); + + $integrationData = $this->createFormIntegration('email', $form->id, [ + 'send_to' => 'test@test.com', + 'sender_name' => 'OpnForm', + 'subject' => 'New form submission', + 'email_content' => 'Hello there 👋
Test body', + 'include_submission_data' => true, + 'include_hidden_fields_submission_data' => false, + 'reply_to' => null, + ]); + + $formData = [ + $emailProperty['id'] => 'reply@example.com', + ]; + + $event = new \App\Events\Forms\FormSubmitted($form, $formData); + $mailable = new FormEmailNotification($event, $integrationData, 'mail'); + $notifiable = new AnonymousNotifiable(); + $notifiable->route('mail', 'test@test.com'); + $renderedMail = $mailable->toMail($notifiable); + expect($renderedMail->replyTo[0][0])->toBe($form->creator->email); +});