diff --git a/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-96149-EXTfromEmailFinisherAlwaysUsesFluidEmail.rst b/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-96149-EXTfromEmailFinisherAlwaysUsesFluidEmail.rst new file mode 100644 index 0000000000000000000000000000000000000000..43802e8de717145780abc9f9fbb40a0efbd0647b --- /dev/null +++ b/typo3/sysext/core/Documentation/Changelog/12.0/Breaking-96149-EXTfromEmailFinisherAlwaysUsesFluidEmail.rst @@ -0,0 +1,46 @@ +.. include:: ../../Includes.txt + +================================================================ +Breaking: #96149 - EXT:from EmailFinisher always uses FluidEmail +================================================================ + +See :issue:`96149` + +Description +=========== + +In recent versions, the :php:`EmailFinisher` of EXT:from allowed sending +emails with either :php:`StandaloneView` or via :php:`FluidEmail`, which +has been introduced in TYPO3 v10. The :php:`StandaloneView` option has +therefore now been removed together with the :file:`Html.html` and +:file:`Plaintext.html` templates. + +Impact +====== + +Since the EXT:from :php:`EmailFinisher` is now always using :php:`FluidEmail` +for sending emails, the :yaml:`templatePathAndFilename` is not evaluated +anymore. For forms, which still define custom templates with this option, +a fallback kicks in, sending the emails with the default EXT:form +:php:`FluidEmail` templates. + +Also the :yaml:`useFluidEmail` configuration option, previously used to +allow a smooth migration path is now obsolete and can safely be removed +from any form finisher configuration. + + +Affected Installations +====================== + +Installations, which have not yet switched to :php:`FluidEmail`, while using +custom email templates, configured with :yaml:`templatePathAndFilename`. + +Migration +========= + +In case you use custom email templates, replace :yaml:`templatePathAndFilename` +with the :yaml:`templateName` and :yaml:`templateRootPaths` options. Also +make sure, you have separate template files for the used formats, e.g. +:file:`ContactForm.html` and :file:`ContactForm.txt`. + +.. index:: YAML, NotScanned, ext:form diff --git a/typo3/sysext/form/Classes/Domain/Finishers/EmailFinisher.php b/typo3/sysext/form/Classes/Domain/Finishers/EmailFinisher.php index 9ab5a011f7a6ec3786f27d47d4365c61f3d42ff8..c84eaadf6bdc1d9b686c6efb78cde4b355de1000 100644 --- a/typo3/sysext/form/Classes/Domain/Finishers/EmailFinisher.php +++ b/typo3/sysext/form/Classes/Domain/Finishers/EmailFinisher.php @@ -21,10 +21,8 @@ use Psr\Http\Message\ServerRequestInterface; use Symfony\Component\Mime\Address; use TYPO3\CMS\Core\Mail\FluidEmail; use TYPO3\CMS\Core\Mail\Mailer; -use TYPO3\CMS\Core\Mail\MailMessage; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Extbase\Domain\Model\FileReference; -use TYPO3\CMS\Fluid\View\StandaloneView; use TYPO3\CMS\Fluid\View\TemplatePaths; use TYPO3\CMS\Form\Domain\Finishers\Exception\FinisherException; use TYPO3\CMS\Form\Domain\Model\FormElements\FileUpload; @@ -37,8 +35,7 @@ use TYPO3\CMS\Form\ViewHelpers\RenderRenderableViewHelper; * * Options: * - * - templatePathAndFilename (mandatory for Mail): Template path and filename for the mail body - * - templateName (mandatory for FluidEmail): Template name for the mail body + * - templateName (mandatory): Template name for the mail body * - templateRootPaths: root paths for the templates * - layoutRootPaths: root paths for the layouts * - partialRootPaths: root paths for the partials @@ -55,6 +52,7 @@ use TYPO3\CMS\Form\ViewHelpers\RenderRenderableViewHelper; * - replyToRecipients: Email addresses and human-readable names of the reply-to recipients * - carbonCopyRecipients: Email addresses and human-readable names of the copy recipients * - blindCarbonCopyRecipients: Email addresses and human-readable names of the blind copy recipients + * - title: The title of the email - If not set "subject" is used by default * * Scope: frontend */ @@ -99,7 +97,6 @@ class EmailFinisher extends AbstractFinisher $blindCarbonCopyRecipients = $this->getRecipients('blindCarbonCopyRecipients'); $addHtmlPart = $this->parseOption('addHtmlPart') ? true : false; $attachUploads = $this->parseOption('attachUploads'); - $useFluidEmail = $this->parseOption('useFluidEmail'); $title = $this->parseOption('title'); $title = is_string($title) && $title !== '' ? $title : $subject; @@ -121,17 +118,13 @@ class EmailFinisher extends AbstractFinisher $translationService->setLanguage($this->options['translation']['language']); } - $mail = $useFluidEmail - ? $this - ->initializeFluidEmail($formRuntime) - ->format($addHtmlPart ? FluidEmail::FORMAT_BOTH : FluidEmail::FORMAT_PLAIN) - ->assign('title', $title) - : GeneralUtility::makeInstance(MailMessage::class); - - $mail + $mail = $this + ->initializeFluidEmail($formRuntime) ->from(new Address($senderAddress, $senderName)) ->to(...$recipients) - ->subject($subject); + ->subject($subject) + ->format($addHtmlPart ? FluidEmail::FORMAT_BOTH : FluidEmail::FORMAT_PLAIN) + ->assign('title', $title); if (!empty($replyToRecipients)) { $mail->replyTo(...$replyToRecipients); @@ -145,33 +138,6 @@ class EmailFinisher extends AbstractFinisher $mail->bcc(...$blindCarbonCopyRecipients); } - if (!$useFluidEmail) { - $parts = [ - [ - 'format' => 'Plaintext', - 'contentType' => 'text/plain', - ], - ]; - - if ($addHtmlPart) { - $parts[] = [ - 'format' => 'Html', - 'contentType' => 'text/html', - ]; - } - - foreach ($parts as $i => $part) { - $standaloneView = $this->initializeStandaloneView($formRuntime, $part['format']); - $message = $standaloneView->render(); - - if ($part['contentType'] === 'text/plain') { - $mail->text($message); - } else { - $mail->html($message); - } - } - } - if (!empty($languageBackup)) { $translationService->setLanguage($languageBackup); } @@ -191,72 +157,7 @@ class EmailFinisher extends AbstractFinisher } } - $useFluidEmail ? GeneralUtility::makeInstance(Mailer::class)->send($mail) : $mail->send(); - } - - /** - * @param FormRuntime $formRuntime - * @param string $format - * @return StandaloneView - * @throws FinisherException - * @deprecated since v11, will be removed in v12 - */ - protected function initializeStandaloneView(FormRuntime $formRuntime, string $format): StandaloneView - { - trigger_error( - 'Using StandaloneView for EmailFinisher \'' . $this->finisherIdentifier . '\' is deprecated and will be removed in v12. Please use FluidEmail in the finishers configuration instead.', - E_USER_DEPRECATED - ); - - $standaloneView = GeneralUtility::makeInstance(StandaloneView::class); - - if (isset($this->options['templatePathAndFilename'])) { - trigger_error( - 'The option \'templatePathAndFilename\' for EmailFinisher \'' . $this->finisherIdentifier . '\' is deprecated and will be removed in v12. Please use \'templateName\' and \'templateRootPaths\' in the finishers definition instead.', - E_USER_DEPRECATED - ); - // Use local variable instead of augmenting the options to - // keep the format intact when sending multi-format mails - $templatePathAndFilename = strtr($this->options['templatePathAndFilename'], [ - '{@format}' => $format, - ]); - $standaloneView->setTemplatePathAndFilename($templatePathAndFilename); - } else { - if (!isset($this->options['templateName'])) { - throw new FinisherException('The option "templateName" must be set for the EmailFinisher.', 1327058829); - } - // Use local variable instead of augmenting the options to - // keep the format intact when sending multi-format mails - $templateName = strtr($this->options['templateName'], [ - '{@format}' => $format, - ]); - $standaloneView->setTemplate($templateName); - } - - $standaloneView->assign('finisherVariableProvider', $this->finisherContext->getFinisherVariableProvider()); - - if (isset($this->options['templateRootPaths']) && is_array($this->options['templateRootPaths'])) { - $standaloneView->setTemplateRootPaths($this->options['templateRootPaths']); - } - - if (isset($this->options['partialRootPaths']) && is_array($this->options['partialRootPaths'])) { - $standaloneView->setPartialRootPaths($this->options['partialRootPaths']); - } - - if (isset($this->options['layoutRootPaths']) && is_array($this->options['layoutRootPaths'])) { - $standaloneView->setLayoutRootPaths($this->options['layoutRootPaths']); - } - - if (is_array($this->options['variables'] ?? null)) { - $standaloneView->assignMultiple($this->options['variables']); - } - - $standaloneView->assign('form', $formRuntime); - $standaloneView->getRenderingContext() - ->getViewHelperVariableContainer() - ->addOrUpdate(RenderRenderableViewHelper::class, 'formRuntime', $formRuntime); - - return $standaloneView; + GeneralUtility::makeInstance(Mailer::class)->send($mail); } protected function initializeFluidEmail(FormRuntime $formRuntime): FluidEmail diff --git a/typo3/sysext/form/Configuration/Yaml/Finishers/EmailToReceiver.yaml b/typo3/sysext/form/Configuration/Yaml/Finishers/EmailToReceiver.yaml index 74055922edada5daa0da6d48e1d9c5fe697eb03b..4ff7782dd8c4d0e755681e539bcb83ad29744b60 100644 --- a/typo3/sysext/form/Configuration/Yaml/Finishers/EmailToReceiver.yaml +++ b/typo3/sysext/form/Configuration/Yaml/Finishers/EmailToReceiver.yaml @@ -7,7 +7,7 @@ TYPO3: EmailToReceiver: implementationClassName: TYPO3\CMS\Form\Domain\Finishers\EmailFinisher options: - templateName: '{@format}.html' + templateName: 'Default' templateRootPaths: 10: 'EXT:form/Resources/Private/Frontend/Templates/Finishers/Email/' formEditor: @@ -26,7 +26,6 @@ TYPO3: attachUploads: true translation: language: 'default' - useFluidEmail: false title: '' FormEngine: label: tt_content.finishersDefinition.EmailToReceiver.label diff --git a/typo3/sysext/form/Configuration/Yaml/Finishers/EmailToSender.yaml b/typo3/sysext/form/Configuration/Yaml/Finishers/EmailToSender.yaml index 1a9281d3f4e0689f094a7430cec6fb8c27d8ca2c..639c0fff74d1d19cf4e1a854229114bbad0017b5 100644 --- a/typo3/sysext/form/Configuration/Yaml/Finishers/EmailToSender.yaml +++ b/typo3/sysext/form/Configuration/Yaml/Finishers/EmailToSender.yaml @@ -7,7 +7,7 @@ TYPO3: EmailToSender: implementationClassName: TYPO3\CMS\Form\Domain\Finishers\EmailFinisher options: - templateName: '{@format}.html' + templateName: 'Default' templateRootPaths: 10: 'EXT:form/Resources/Private/Frontend/Templates/Finishers/Email/' formEditor: @@ -24,7 +24,6 @@ TYPO3: blindCarbonCopyRecipients: { } addHtmlPart: true attachUploads: true - useFluidEmail: false title: '' FormEngine: label: tt_content.finishersDefinition.EmailToSender.label diff --git a/typo3/sysext/form/Configuration/Yaml/FormElements/Form.yaml b/typo3/sysext/form/Configuration/Yaml/FormElements/Form.yaml index 04427d5dd741782aec4113311f7a588fc678d469..715721faf1ffa48ec799d99260c752c07c24b7a2 100644 --- a/typo3/sysext/form/Configuration/Yaml/FormElements/Form.yaml +++ b/typo3/sysext/form/Configuration/Yaml/FormElements/Form.yaml @@ -193,12 +193,6 @@ TYPO3: 10: value: default label: formEditor.elements.Form.finisher.EmailToSender.editor.language.1 - 1300: - identifier: useFluidEmail - templateName: Inspector-CheckboxEditor - label: formEditor.elements.Form.finisher.EmailToSender.editor.useFluidEmail.label - propertyPath: options.useFluidEmail - fieldExplanationText: formEditor.elements.Form.finisher.EmailToSender.editor.useFluidEmail.fieldExplanationText 1400: identifier: title templateName: Inspector-TextEditor @@ -334,12 +328,6 @@ TYPO3: 10: value: default label: formEditor.elements.Form.finisher.EmailToReceiver.editor.language.1 - 1300: - identifier: useFluidEmail - templateName: Inspector-CheckboxEditor - label: formEditor.elements.Form.finisher.EmailToReceiver.editor.useFluidEmail.label - propertyPath: options.useFluidEmail - fieldExplanationText: formEditor.elements.Form.finisher.EmailToReceiver.editor.useFluidEmail.fieldExplanationText 1400: identifier: title templateName: Inspector-TextEditor diff --git a/typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Yaml/NewForms/SimpleContactForm.yaml b/typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Yaml/NewForms/SimpleContactForm.yaml index 26d5597095c0ceb4cc11fda3a25ebf9092c01b01..38c75f44ba1ba0643b782a02b4cd802a3a5303e9 100644 --- a/typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Yaml/NewForms/SimpleContactForm.yaml +++ b/typo3/sysext/form/Resources/Private/Backend/Templates/FormEditor/Yaml/NewForms/SimpleContactForm.yaml @@ -18,7 +18,6 @@ finishers: attachUploads: 'true' translation: language: '' - useFluidEmail: 'true' title: 'Confirmation of your message' renderables: diff --git a/typo3/sysext/form/Resources/Private/Frontend/Templates/Finishers/Email/Html.html b/typo3/sysext/form/Resources/Private/Frontend/Templates/Finishers/Email/Html.html deleted file mode 100644 index 71bba07f762b4fb7281ec1e8adbe44bc934e74b9..0000000000000000000000000000000000000000 --- a/typo3/sysext/form/Resources/Private/Frontend/Templates/Finishers/Email/Html.html +++ /dev/null @@ -1,52 +0,0 @@ -{namespace formvh=TYPO3\CMS\Form\ViewHelpers} -<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> -<html> -<head> - <title></title> - <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> - <meta name="format-detection" content="telephone=no"> -</head> -<body> - <table width="600" cellpadding="0" cellspacing="0" border="0"> - <formvh:renderAllFormValues renderable="{form.formDefinition}" as="formValue"> - <tr> - <f:if condition="{formValue.isSection}"> - <f:then> - <td colspan="2"><b>{formvh:translateElementProperty(element: formValue.element, property: 'label')}</b></td> - </f:then> - <f:else> - <td width="600" valign="top" align="left">{formvh:translateElementProperty(element: formValue.element, property: 'label')}</td> - <td width="600" valign="top" align="left"> - <f:if condition="{formValue.value}"> - <f:then> - <f:if condition="{formValue.isMultiValue}"> - <f:then> - <table cellspacing="0" border="0"> - <f:for each="{formValue.processedValue}" as="value"> - <tr> - <td>{value}</td> - </tr> - </f:for> - </table> - </f:then> - <f:else> - <table cellspacing="0" border="0"> - <tr> - <td><f:format.nl2br>{formValue.processedValue}</f:format.nl2br></td> - </tr> - </table> - </f:else> - </f:if> - </f:then> - <f:else> - - - </f:else> - </f:if> - </td> - </f:else> - </f:if> - </tr> - </formvh:renderAllFormValues> - </table> -</body> -</html> diff --git a/typo3/sysext/form/Resources/Private/Frontend/Templates/Finishers/Email/Plaintext.html b/typo3/sysext/form/Resources/Private/Frontend/Templates/Finishers/Email/Plaintext.html deleted file mode 100644 index 3e8062815a5ea022a6ee232f56946846067cbbc6..0000000000000000000000000000000000000000 --- a/typo3/sysext/form/Resources/Private/Frontend/Templates/Finishers/Email/Plaintext.html +++ /dev/null @@ -1,14 +0,0 @@ -<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" xmlns:formvh="http://typo3.org/ns/TYPO3/CMS/Form/ViewHelpers" data-namespace-typo3-fluid="true"> -<formvh:renderAllFormValues renderable="{form.formDefinition}" as="formValue"><f:spaceless> - <f:if condition="{formValue.isMultiValue}"> - <f:then> - <f:if condition="{formValue.isSection}"><f:then>*** <formvh:translateElementProperty element="{formValue.element}" property="label" /> ***</f:then><f:else><formvh:translateElementProperty element="{formValue.element}" property="label" />: <f:for each="{formValue.processedValue}" as="singleValue">- {singleValue} - </f:for></f:else></f:if> - </f:then> - <f:else> - <f:if condition="{formValue.isSection}"><f:then>*** <formvh:translateElementProperty element="{formValue.element}" property="label" /> ***</f:then><f:else><formvh:translateElementProperty element="{formValue.element}" property="label" />: <f:if condition="{formValue.processedValue}"><f:then>{formValue.processedValue -> f:format.raw()}</f:then><f:else>-</f:else></f:if></f:else></f:if> - </f:else> - </f:if> -</f:spaceless> -</formvh:renderAllFormValues> -</html> diff --git a/typo3/sysext/form/Resources/Private/Language/Database.xlf b/typo3/sysext/form/Resources/Private/Language/Database.xlf index 19badba8f5e3d7273f478139c0570c5c701586e3..daa159bb663ba7de63870d48a362d3c0c9631a12 100644 --- a/typo3/sysext/form/Resources/Private/Language/Database.xlf +++ b/typo3/sysext/form/Resources/Private/Language/Database.xlf @@ -656,17 +656,11 @@ <trans-unit id="formEditor.elements.Form.finisher.EmailToSender.editor.language.1" resname="formEditor.elements.Form.finisher.EmailToSender.editor.language.1" xml:space="preserve"> <source>EN</source> </trans-unit> - <trans-unit id="formEditor.elements.Form.finisher.EmailToSender.editor.useFluidEmail.label" resname="formEditor.elements.Form.finisher.EmailToSender.editor.useFluidEmail.label" xml:space="preserve"> - <source>Use FluidEmail</source> - </trans-unit> - <trans-unit id="formEditor.elements.Form.finisher.EmailToSender.editor.useFluidEmail.fieldExplanationText" resname="formEditor.elements.Form.finisher.EmailToSender.editor.useFluidEmail.fieldExplanationText" xml:space="preserve"> - <source>If enabled, the email will be sent using the new FluidEmail rendering.</source> - </trans-unit> - <trans-unit id="formEditor.elements.Form.finisher.EmailToSender.editor.title.label" resname="formEditor.elements.Form.finisher.EmailToSender.editor.useFluidEmail.label" xml:space="preserve"> + <trans-unit id="formEditor.elements.Form.finisher.EmailToSender.editor.title.label" resname="formEditor.elements.Form.finisher.EmailToSender.editor.title.label" xml:space="preserve"> <source>Title</source> </trans-unit> - <trans-unit id="formEditor.elements.Form.finisher.EmailToSender.editor.title.fieldExplanationText" resname="formEditor.elements.Form.finisher.EmailToSender.editor.useFluidEmail.fieldExplanationText" xml:space="preserve"> - <source>Only used if FluidEmail is enabled.</source> + <trans-unit id="formEditor.elements.Form.finisher.EmailToSender.editor.title.fieldExplanationText" resname="formEditor.elements.Form.finisher.EmailToSender.editor.title.fieldExplanationText" xml:space="preserve"> + <source>The title, being shown in the Email</source> </trans-unit> <trans-unit id="formEditor.elements.Form.finisher.EmailToReceiver.editor.header.label" resname="formEditor.elements.Form.finisher.EmailToReceiver.editor.header.label" xml:space="preserve"> @@ -717,17 +711,11 @@ <trans-unit id="formEditor.elements.Form.finisher.EmailToReceiver.editor.language.1" resname="formEditor.elements.Form.finisher.EmailToReceiver.editor.language.1" xml:space="preserve"> <source>EN</source> </trans-unit> - <trans-unit id="formEditor.elements.Form.finisher.EmailToReceiver.editor.useFluidEmail.label" resname="formEditor.elements.Form.finisher.EmailToReceiver.editor.useFluidEmail.label" xml:space="preserve"> - <source>Use FluidEmail</source> - </trans-unit> - <trans-unit id="formEditor.elements.Form.finisher.EmailToReceiver.editor.useFluidEmail.fieldExplanationText" resname="formEditor.elements.Form.finisher.EmailToReceiver.editor.useFluidEmail.fieldExplanationText" xml:space="preserve"> - <source>If enabled, the email will be sent using the new FluidEmail rendering.</source> - </trans-unit> - <trans-unit id="formEditor.elements.Form.finisher.EmailToReceiver.editor.title.label" resname="formEditor.elements.Form.finisher.EmailToSender.editor.useFluidEmail.label" xml:space="preserve"> + <trans-unit id="formEditor.elements.Form.finisher.EmailToReceiver.editor.title.label" resname="formEditor.elements.Form.finisher.EmailToSender.editor.title.label" xml:space="preserve"> <source>Title</source> </trans-unit> - <trans-unit id="formEditor.elements.Form.finisher.EmailToReceiver.editor.title.fieldExplanationText" resname="formEditor.elements.Form.finisher.EmailToSender.editor.useFluidEmail.fieldExplanationText" xml:space="preserve"> - <source>Only used if FluidEmail is enabled.</source> + <trans-unit id="formEditor.elements.Form.finisher.EmailToReceiver.editor.title.fieldExplanationText" resname="formEditor.elements.Form.finisher.EmailToSender.editor.title.fieldExplanationText" xml:space="preserve"> + <source>The title, being shown in the Email</source> </trans-unit> <trans-unit id="formEditor.elements.Form.finisher.Redirect.editor.header.label" resname="formEditor.elements.Form.finisher.Redirect.editor.header.label" xml:space="preserve">