diff --git a/config/doctrine/model/DoubleOptInSession.orm.yml b/config/doctrine/model/DoubleOptInSession.orm.yml index c19c79a5..ab5aff9c 100644 --- a/config/doctrine/model/DoubleOptInSession.orm.yml +++ b/config/doctrine/model/DoubleOptInSession.orm.yml @@ -43,7 +43,4 @@ FormBuilderBundle\Model\DoubleOptInSession: joinColumn: name: form_definition referencedColumnName: id - onDelete: CASCADE - uniqueConstraints: - email_form_definition: - columns: [email, form_definition, applied] \ No newline at end of file + onDelete: CASCADE \ No newline at end of file diff --git a/src/Event/SubmissionEvent.php b/src/Event/SubmissionEvent.php index 6b50b70d..5d750344 100644 --- a/src/Event/SubmissionEvent.php +++ b/src/Event/SubmissionEvent.php @@ -2,6 +2,7 @@ namespace FormBuilderBundle\Event; +use FormBuilderBundle\Model\DoubleOptInSessionInterface; use Symfony\Component\Form\FormInterface; use Symfony\Component\HttpFoundation\Request; @@ -12,6 +13,7 @@ class SubmissionEvent extends BaseSubmissionEvent protected ?string $redirectUri = null; protected bool $outputWorkflowFinisherDisabled = false; + protected ?DoubleOptInSessionInterface $doubleOptInSession = null; public function __construct( Request $request, @@ -66,4 +68,19 @@ public function getFunnelRuntimeData(): ?array { return $this->funnelRuntimeData; } + + public function hasDoubleOptInSession(): bool + { + return $this->doubleOptInSession instanceof DoubleOptInSessionInterface; + } + + public function getDoubleOptInSession(): ?DoubleOptInSessionInterface + { + return $this->doubleOptInSession; + } + + public function setDoubleOptInSession(?DoubleOptInSessionInterface $doubleOptInSession): void + { + $this->doubleOptInSession = $doubleOptInSession; + } } diff --git a/src/MailEditor/Parser/PlaceholderParser.php b/src/MailEditor/Parser/PlaceholderParser.php index 92c85b0b..f4ab91b5 100644 --- a/src/MailEditor/Parser/PlaceholderParser.php +++ b/src/MailEditor/Parser/PlaceholderParser.php @@ -122,6 +122,7 @@ protected function parseFieldTag(array $tag, ?array $containerData = null): ?str } $attributes->set('form', $this->form); + $attributes->set('raw_output_data', $this->outputData); return $widget->getValueForOutput($attributes, $this->layoutType); } diff --git a/src/MailEditor/Widget/DoubleOptInSessionAdditionalDataWidget.php b/src/MailEditor/Widget/DoubleOptInSessionAdditionalDataWidget.php new file mode 100644 index 00000000..cec72566 --- /dev/null +++ b/src/MailEditor/Widget/DoubleOptInSessionAdditionalDataWidget.php @@ -0,0 +1,54 @@ + [ + 'type' => 'input', + 'defaultValue' => null, + 'label' => 'form_builder.mail_editor.widget_provider.double_opt_in_session.additional_data_field' + ], + ]; + } + + public function getValueForOutput(AttributeBag $attributeBag, string $layoutType): string + { + $rawOutputData = $attributeBag->get('raw_output_data', []); + + if (!array_key_exists('double_opt_in_session', $rawOutputData)) { + return '[NO VALUE]'; + } + + $doubleOptInSession = $rawOutputData['double_opt_in_session']; + if (!is_array($doubleOptInSession)) { + return '[NO VALUE]'; + } + + $field = $attributeBag->get('field', null); + $additionalData = $doubleOptInSession['additional_data']; + + if (!array_key_exists($field, $additionalData)) { + return '[NO VALUE]'; + } + + return (string) $additionalData[$field]; + } +} diff --git a/src/MailEditor/Widget/DoubleOptInSessionEmailWidget.php b/src/MailEditor/Widget/DoubleOptInSessionEmailWidget.php new file mode 100644 index 00000000..10cc8e68 --- /dev/null +++ b/src/MailEditor/Widget/DoubleOptInSessionEmailWidget.php @@ -0,0 +1,45 @@ +get('raw_output_data', []); + + if (!array_key_exists('double_opt_in_session', $rawOutputData)) { + return '[NO VALUE]'; + } + + $doubleOptInSession = $rawOutputData['double_opt_in_session']; + if (!is_array($doubleOptInSession)) { + return '[NO VALUE]'; + } + + $email = $doubleOptInSession['email'] ?? null; + if ($email === null) { + return '[NO VALUE]'; + } + + return $email; + } +} diff --git a/src/OutputWorkflow/Channel/Email/EmailOutputChannel.php b/src/OutputWorkflow/Channel/Email/EmailOutputChannel.php index ab3edcb1..ef3aa714 100644 --- a/src/OutputWorkflow/Channel/Email/EmailOutputChannel.php +++ b/src/OutputWorkflow/Channel/Email/EmailOutputChannel.php @@ -37,13 +37,18 @@ public function getUsedFormFieldNames(array $channelConfiguration): array */ public function dispatchOutputProcessing(SubmissionEvent $submissionEvent, string $workflowName, array $channelConfiguration): void { - $locale = $submissionEvent->getRequest()->getLocale(); + $locale = $submissionEvent->getLocale() ?? $submissionEvent->getRequest()->getLocale(); $form = $submissionEvent->getForm(); $formRuntimeData = $submissionEvent->getFormRuntimeData(); $localizedConfig = $this->validateOutputConfig($channelConfiguration, $locale); - $this->channelWorker->process($form, $localizedConfig, $formRuntimeData, $workflowName, $locale); + $context = [ + 'locale' => $locale, + 'doubleOptInSession' => $submissionEvent->getDoubleOptInSession(), + ]; + + $this->channelWorker->process($form, $localizedConfig, $formRuntimeData, $workflowName, $context); } /** diff --git a/src/OutputWorkflow/Channel/Email/EmailOutputChannelWorker.php b/src/OutputWorkflow/Channel/Email/EmailOutputChannelWorker.php index 89751a12..0360058d 100644 --- a/src/OutputWorkflow/Channel/Email/EmailOutputChannelWorker.php +++ b/src/OutputWorkflow/Channel/Email/EmailOutputChannelWorker.php @@ -7,6 +7,7 @@ use FormBuilderBundle\Exception\OutputWorkflow\GuardChannelException; use FormBuilderBundle\Exception\OutputWorkflow\GuardException; use FormBuilderBundle\Exception\OutputWorkflow\GuardOutputWorkflowException; +use FormBuilderBundle\Model\DoubleOptInSessionInterface; use Pimcore\Mail; use Pimcore\Model\Document; use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; @@ -27,7 +28,7 @@ public function __construct( /** * @throws \Exception */ - public function process(FormInterface $form, array $channelConfiguration, array $formRuntimeData, string $workflowName, string $locale): void + public function process(FormInterface $form, array $channelConfiguration, array $formRuntimeData, string $workflowName, array $context = []): void { /** @var FormDataInterface $formData */ $formData = $form->getData(); @@ -36,6 +37,7 @@ public function process(FormInterface $form, array $channelConfiguration, array $forcePlainText = $channelConfiguration['forcePlainText']; $disableDefaultMailBody = $channelConfiguration['disableDefaultMailBody']; $disableMailLogging = $channelConfiguration['disableMailLogging'] ?? false; + $doubleOptInSession = $context['doubleOptInSession'] ?? null; $mailTemplateId = $mailTemplate['id']; $mailTemplate = is_numeric($mailTemplateId) ? Document\Email::getById($mailTemplateId) : null; @@ -44,13 +46,18 @@ public function process(FormInterface $form, array $channelConfiguration, array throw new \Exception('Invalid Email Document Id: ' . $mailTemplateId); } - $mail = $this->mailParser->create($mailTemplate, $form, $channelConfiguration, $locale); + $mail = $this->mailParser->create($mailTemplate, $form, $channelConfiguration, $context); $forceSubmissionAsPlainText = (bool) $forcePlainText; $mail->setParam('_form_builder_output_workflow_name', $workflowName); $mail->setParam('_form_builder_id', (int) $formData->getFormDefinition()->getId()); $mail->setParam('_form_builder_preset', $formRuntimeData['form_preset'] === 'custom' ? null : $formRuntimeData['form_preset']); + if ($doubleOptInSession instanceof DoubleOptInSessionInterface) { + $mail->setParam('_form_builder_double_opt_in_token', $doubleOptInSession->getTokenAsString()); + $mail->setParam('_form_builder_double_opt_in_session_email', $doubleOptInSession->getEmail()); + } + if ($disableDefaultMailBody === true) { $mail->setParam('_form_builder_disabled_default_mail_body', 1); } diff --git a/src/OutputWorkflow/FormSubmissionFinisher.php b/src/OutputWorkflow/FormSubmissionFinisher.php index 269aeda5..97edf5ab 100644 --- a/src/OutputWorkflow/FormSubmissionFinisher.php +++ b/src/OutputWorkflow/FormSubmissionFinisher.php @@ -10,6 +10,7 @@ use FormBuilderBundle\Form\Data\FormDataInterface; use FormBuilderBundle\Form\FormErrorsSerializerInterface; use FormBuilderBundle\Manager\DoubleOptInManager; +use FormBuilderBundle\Model\DoubleOptInSessionInterface; use FormBuilderBundle\Model\FormDefinitionInterface; use FormBuilderBundle\Model\OutputWorkflowInterface; use FormBuilderBundle\Session\FlashBagManagerInterface; @@ -54,6 +55,15 @@ public function finishWithSuccess(Request $request, SubmissionEvent $submissionE return $this->buildErrorResponse($request, $submissionEvent, 'No valid output workflow found.'); } + /** @var FormDataInterface $data */ + $data = $submissionEvent->getForm()->getData(); + $formDefinition = $data->getFormDefinition(); + $doubleOptInSession = $this->doubleOptInManager->findDoubleOptInSession($formDefinition, $submissionEvent->getFormRuntimeData()); + + if ($doubleOptInSession instanceof DoubleOptInSessionInterface) { + $submissionEvent->setDoubleOptInSession($doubleOptInSession); + } + try { $this->outputWorkflowDispatcher->dispatch($outputWorkflow, $submissionEvent); } catch (GuardOutputWorkflowException $e) { @@ -110,7 +120,6 @@ protected function buildErrorResponse(Request $request, SubmissionEvent|DoubleOp $data = $submissionEvent->getForm()->getData(); $formDefinition = $data->getFormDefinition(); $redirectUri = $submissionEvent->hasRedirectUri() ? $submissionEvent->getRedirectUri() : null; - } else { $flashBagPrefix = 'formbuilder_double_opt_in'; $formDefinition = $submissionEvent->getFormDefinition(); @@ -154,10 +163,10 @@ protected function buildSuccessResponse(Request $request, SubmissionEvent|Double $responseMessages ]; - if ($submissionEvent instanceof SubmissionEvent) { + if ($submissionEvent instanceof SubmissionEvent && $submissionEvent->hasDoubleOptInSession()) { try { - $this->doubleOptInManager->redeemDoubleOptInSessionToken($formDefinition, $submissionEvent->getFormRuntimeData()); - } catch(\Throwable $e) { + $this->doubleOptInManager->redeemDoubleOptInSessionToken($submissionEvent->getDoubleOptInSession()); + } catch (\Throwable $e) { return $this->buildErrorResponse($request, $submissionEvent, $e->getMessage()); } }