|
9 | 9 |
|
10 | 10 | use OCA\Forms\Activity\ActivityManager; |
11 | 11 | use OCA\Forms\Constants; |
| 12 | +use OCA\Forms\Db\AnswerMapper; |
12 | 13 | use OCA\Forms\Db\Form; |
13 | 14 | use OCA\Forms\Db\FormMapper; |
14 | 15 | use OCA\Forms\Db\OptionMapper; |
|
34 | 35 | use OCP\IUser; |
35 | 36 | use OCP\IUserManager; |
36 | 37 | use OCP\IUserSession; |
| 38 | +use OCP\Mail\IMailer; |
37 | 39 | use OCP\Search\ISearchQuery; |
38 | 40 | use OCP\Security\ISecureRandom; |
39 | 41 | use OCP\Share\IShare; |
@@ -67,6 +69,8 @@ public function __construct( |
67 | 69 | private IL10N $l10n, |
68 | 70 | private LoggerInterface $logger, |
69 | 71 | private IEventDispatcher $eventDispatcher, |
| 72 | + private IMailer $mailer, |
| 73 | + private AnswerMapper $answerMapper, |
70 | 74 | ) { |
71 | 75 | $this->currentUser = $userSession->getUser(); |
72 | 76 | } |
@@ -737,6 +741,151 @@ public function notifyNewSubmission(Form $form, Submission $submission): void { |
737 | 741 | } |
738 | 742 |
|
739 | 743 | $this->eventDispatcher->dispatchTyped(new FormSubmittedEvent($form, $submission)); |
| 744 | + |
| 745 | + // Send confirmation email if enabled |
| 746 | + $this->sendConfirmationEmail($form, $submission); |
| 747 | + } |
| 748 | + |
| 749 | + /** |
| 750 | + * Send confirmation email to the respondent |
| 751 | + * |
| 752 | + * @param Form $form The form that was submitted |
| 753 | + * @param Submission $submission The submission |
| 754 | + */ |
| 755 | + private function sendConfirmationEmail(Form $form, Submission $submission): void { |
| 756 | + // Check if confirmation email is enabled |
| 757 | + if (!$form->getConfirmationEmailEnabled()) { |
| 758 | + return; |
| 759 | + } |
| 760 | + |
| 761 | + $subject = $form->getConfirmationEmailSubject(); |
| 762 | + $body = $form->getConfirmationEmailBody(); |
| 763 | + |
| 764 | + // If no subject or body is set, use defaults |
| 765 | + if (empty($subject)) { |
| 766 | + $subject = $this->l10n->t('Thank you for your submission'); |
| 767 | + } |
| 768 | + if (empty($body)) { |
| 769 | + $body = $this->l10n->t('Thank you for submitting the form "%s".', [$form->getTitle()]); |
| 770 | + } |
| 771 | + |
| 772 | + // Get questions and answers |
| 773 | + $questions = $this->getQuestions($form->getId()); |
| 774 | + $answers = $this->answerMapper->findBySubmission($submission->getId()); |
| 775 | + |
| 776 | + // Build a map of question IDs to questions and answers |
| 777 | + $questionMap = []; |
| 778 | + foreach ($questions as $question) { |
| 779 | + $questionMap[$question['id']] = $question; |
| 780 | + } |
| 781 | + |
| 782 | + $answerMap = []; |
| 783 | + foreach ($answers as $answer) { |
| 784 | + $questionId = $answer->getQuestionId(); |
| 785 | + if (!isset($answerMap[$questionId])) { |
| 786 | + $answerMap[$questionId] = []; |
| 787 | + } |
| 788 | + $answerMap[$questionId][] = $answer->getText(); |
| 789 | + } |
| 790 | + |
| 791 | + // Find email address from answers |
| 792 | + $recipientEmail = null; |
| 793 | + foreach ($questions as $question) { |
| 794 | + if ($question['type'] !== Constants::ANSWER_TYPE_SHORT) { |
| 795 | + continue; |
| 796 | + } |
| 797 | + |
| 798 | + $extraSettings = (array)($question['extraSettings'] ?? []); |
| 799 | + $validationType = $extraSettings['validationType'] ?? null; |
| 800 | + if ($validationType !== 'email') { |
| 801 | + continue; |
| 802 | + } |
| 803 | + |
| 804 | + $questionId = $question['id']; |
| 805 | + if (empty($answerMap[$questionId])) { |
| 806 | + continue; |
| 807 | + } |
| 808 | + |
| 809 | + $emailValue = $answerMap[$questionId][0]; |
| 810 | + if ($this->mailer->validateMailAddress($emailValue)) { |
| 811 | + $recipientEmail = $emailValue; |
| 812 | + break; |
| 813 | + } |
| 814 | + } |
| 815 | + |
| 816 | + // If no email found, cannot send confirmation |
| 817 | + if (empty($recipientEmail)) { |
| 818 | + $this->logger->debug('No valid email address found in submission for confirmation email', [ |
| 819 | + 'formId' => $form->getId(), |
| 820 | + 'submissionId' => $submission->getId(), |
| 821 | + ]); |
| 822 | + return; |
| 823 | + } |
| 824 | + |
| 825 | + // Replace placeholders in subject and body |
| 826 | + $replacements = [ |
| 827 | + '{formTitle}' => $form->getTitle(), |
| 828 | + '{formDescription}' => $form->getDescription() ?? '', |
| 829 | + ]; |
| 830 | + |
| 831 | + // Add field placeholders (e.g., {name}, {email}) |
| 832 | + foreach ($questions as $question) { |
| 833 | + $questionId = $question['id']; |
| 834 | + $questionName = $question['name'] ?? ''; |
| 835 | + $questionText = $question['text'] ?? ''; |
| 836 | + |
| 837 | + // Use question name if available, otherwise use text |
| 838 | + $fieldKey = !empty($questionName) ? $questionName : $questionText; |
| 839 | + // Sanitize field key for placeholder (remove special chars, lowercase) |
| 840 | + $fieldKey = strtolower(preg_replace('/[^a-zA-Z0-9]/', '', $fieldKey)); |
| 841 | + |
| 842 | + if (!empty($answerMap[$questionId])) { |
| 843 | + $answerValue = implode('; ', $answerMap[$questionId]); |
| 844 | + $replacements['{' . $fieldKey . '}'] = $answerValue; |
| 845 | + // Also support {questionName} format |
| 846 | + if (!empty($questionName)) { |
| 847 | + $replacements['{' . strtolower(preg_replace('/[^a-zA-Z0-9]/', '', $questionName)) . '}'] = $answerValue; |
| 848 | + } |
| 849 | + } |
| 850 | + } |
| 851 | + |
| 852 | + // Apply replacements |
| 853 | + $subject = str_replace(array_keys($replacements), array_values($replacements), $subject); |
| 854 | + $body = str_replace(array_keys($replacements), array_values($replacements), $body); |
| 855 | + |
| 856 | + try { |
| 857 | + $message = $this->mailer->createMessage(); |
| 858 | + $message->setSubject($subject); |
| 859 | + $message->setPlainBody($body); |
| 860 | + $message->setTo([$recipientEmail]); |
| 861 | + |
| 862 | + // Set from address to form owner or system default |
| 863 | + $owner = $this->userManager->get($form->getOwnerId()); |
| 864 | + if ($owner instanceof IUser) { |
| 865 | + $ownerEmail = $owner->getEMailAddress(); |
| 866 | + if (!empty($ownerEmail)) { |
| 867 | + $message->setFrom([$ownerEmail => $owner->getDisplayName()]); |
| 868 | + } |
| 869 | + } |
| 870 | + |
| 871 | + $this->mailer->send($message); |
| 872 | + $this->logger->debug('Confirmation email sent successfully', [ |
| 873 | + 'formId' => $form->getId(), |
| 874 | + 'submissionId' => $submission->getId(), |
| 875 | + 'recipient' => $recipientEmail, |
| 876 | + ]); |
| 877 | + } catch (\Exception $e) { |
| 878 | + // Handle exceptions silently, as this is not critical. |
| 879 | + // We don't want to break the submission process just because of an email error. |
| 880 | + $this->logger->error( |
| 881 | + 'Error while sending confirmation email', |
| 882 | + [ |
| 883 | + 'exception' => $e, |
| 884 | + 'formId' => $form->getId(), |
| 885 | + 'submissionId' => $submission->getId(), |
| 886 | + ] |
| 887 | + ); |
| 888 | + } |
740 | 889 | } |
741 | 890 |
|
742 | 891 | /** |
|
0 commit comments