diff --git a/typo3/sysext/form/Classes/Domain/Finishers/EmailFinisher.php b/typo3/sysext/form/Classes/Domain/Finishers/EmailFinisher.php index 4dfd931fcd145aef5b6a451f345ae3cd009ff137..811cc02aa36f594cfe6dca7d7e6cf59ae3eace71 100644 --- a/typo3/sysext/form/Classes/Domain/Finishers/EmailFinisher.php +++ b/typo3/sysext/form/Classes/Domain/Finishers/EmailFinisher.php @@ -160,38 +160,42 @@ class EmailFinisher extends AbstractFinisher GeneralUtility::makeInstance(MailerInterface::class)->send($mail); } - protected function initializeFluidEmail(FormRuntime $formRuntime): FluidEmail + protected function initializeTemplatePaths(array $globalConfig, array $localConfig): TemplatePaths { - $templateConfiguration = $GLOBALS['TYPO3_CONF_VARS']['MAIL']; - - if (is_array($this->options['templateRootPaths'] ?? null)) { - $templateConfiguration['templateRootPaths'] = array_replace_recursive( - $templateConfiguration['templateRootPaths'], - $this->options['templateRootPaths'] + if (is_array($localConfig['templateRootPaths'] ?? null)) { + $globalConfig['templateRootPaths'] = array_replace_recursive( + $globalConfig['templateRootPaths'], + $localConfig['templateRootPaths'] ); - ksort($templateConfiguration['templateRootPaths']); + ksort($globalConfig['templateRootPaths']); } - if (is_array($this->options['partialRootPaths'] ?? null)) { - $templateConfiguration['partialRootPaths'] = array_replace_recursive( - $templateConfiguration['partialRootPaths'], - $this->options['partialRootPaths'] + if (is_array($localConfig['partialRootPaths'] ?? null)) { + $globalConfig['partialRootPaths'] = array_replace_recursive( + $globalConfig['partialRootPaths'], + $localConfig['partialRootPaths'] ); - ksort($templateConfiguration['partialRootPaths']); + ksort($globalConfig['partialRootPaths']); } - if (is_array($this->options['layoutRootPaths'] ?? null)) { - $templateConfiguration['layoutRootPaths'] = array_replace_recursive( - $templateConfiguration['layoutRootPaths'], - $this->options['layoutRootPaths'] + if (is_array($localConfig['layoutRootPaths'] ?? null)) { + $globalConfig['layoutRootPaths'] = array_replace_recursive( + $globalConfig['layoutRootPaths'], + $localConfig['layoutRootPaths'] ); - ksort($templateConfiguration['layoutRootPaths']); + ksort($globalConfig['layoutRootPaths']); } - $fluidEmail = GeneralUtility::makeInstance( - FluidEmail::class, - GeneralUtility::makeInstance(TemplatePaths::class, $templateConfiguration) + return GeneralUtility::makeInstance(TemplatePaths::class, $globalConfig); + } + + protected function initializeFluidEmail(FormRuntime $formRuntime): FluidEmail + { + $templatePaths = $this->initializeTemplatePaths( + $GLOBALS['TYPO3_CONF_VARS']['MAIL'], + $this->options, ); + $fluidEmail = GeneralUtility::makeInstance(FluidEmail::class, $templatePaths); if (!isset($this->options['templateName']) || $this->options['templateName'] === '') { throw new FinisherException('The option "templateName" must be set to use FluidEmail.', 1599834020); diff --git a/typo3/sysext/form/Tests/Unit/Domain/Finishers/EmailFinisherTest.php b/typo3/sysext/form/Tests/Unit/Domain/Finishers/EmailFinisherTest.php new file mode 100644 index 0000000000000000000000000000000000000000..d6256382c6ed8166707a35d3f2ee4550801ecf31 --- /dev/null +++ b/typo3/sysext/form/Tests/Unit/Domain/Finishers/EmailFinisherTest.php @@ -0,0 +1,174 @@ +<?php + +declare(strict_types=1); + +/* + * This file is part of the TYPO3 CMS project. + * + * It is free software; you can redistribute it and/or modify it under + * the terms of the GNU General Public License, either version 2 + * of the License, or any later version. + * + * For the full copyright and license information, please read the + * LICENSE.txt file that was distributed with this source code. + * + * The TYPO3 project - inspiring people to share! + */ + +namespace TYPO3\CMS\Form\Tests\Unit\Domain\Finishers; + +use PHPUnit\Framework\Attributes\DataProvider; +use PHPUnit\Framework\Attributes\Test; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Form\Domain\Finishers\EmailFinisher; +use TYPO3\TestingFramework\Core\Unit\UnitTestCase; + +final class EmailFinisherTest extends UnitTestCase +{ + public static function templatePathsAreMergedCorrectlyDataProvider(): array + { + return [ + 'default configuration' => [ + 'globalConfig' => [ + 'templateRootPaths' => [ + 0 => 'EXT:core/Resources/Private/Templates/Email/', + 10 => 'EXT:backend/Resources/Private/Templates/Email/', + ], + 'layoutRootPaths' => [ + 0 => 'EXT:core/Resources/Private/Layouts/', + 10 => 'EXT:backend/Resources/Private/Layouts/', + ], + 'partialRootPaths' => [ + 0 => 'EXT:core/Resources/Private/Partials/', + 10 => 'EXT:backend/Resources/Private/Partials/', + ], + ], + 'localConfig' => [ + 'templateRootPaths' => [ + 10 => 'EXT:form/Resources/Private/Frontend/Templates/Finishers/Email/', + ], + 'layoutRootPaths' => [], + 'partialRootPaths' => [], + ], + 'expected' => [ + 'templateRootPaths' => [ + 'EXT:core/Resources/Private/Templates/Email/', + 'EXT:form/Resources/Private/Frontend/Templates/Finishers/Email/', + ], + 'layoutRootPaths' => [ + 'EXT:core/Resources/Private/Layouts/', + 'EXT:backend/Resources/Private/Layouts/', + ], + 'partialRootPaths' => [ + 'EXT:core/Resources/Private/Partials/', + 'EXT:backend/Resources/Private/Partials/', + ], + ], + ], + + 'user-defined form templates' => [ + 'globalConfig' => [ + 'templateRootPaths' => [ + 0 => 'EXT:core/Resources/Private/Templates/Email/', + 10 => 'EXT:backend/Resources/Private/Templates/Email/', + ], + 'layoutRootPaths' => [ + 0 => 'EXT:core/Resources/Private/Layouts/', + 10 => 'EXT:backend/Resources/Private/Layouts/', + ], + 'partialRootPaths' => [ + 0 => 'EXT:core/Resources/Private/Partials/', + 10 => 'EXT:backend/Resources/Private/Partials/', + ], + ], + 'localConfig' => [ + 'templateRootPaths' => [ + 10 => 'EXT:form/Resources/Private/Frontend/Templates/Finishers/Email/', + 20 => 'EXT:myextension/Resources/Private/Templates/Form/Email/', + ], + 'layoutRootPaths' => [], + 'partialRootPaths' => [], + ], + 'expected' => [ + 'templateRootPaths' => [ + 'EXT:core/Resources/Private/Templates/Email/', + 'EXT:form/Resources/Private/Frontend/Templates/Finishers/Email/', + 'EXT:myextension/Resources/Private/Templates/Form/Email/', + ], + 'layoutRootPaths' => [ + 'EXT:core/Resources/Private/Layouts/', + 'EXT:backend/Resources/Private/Layouts/', + ], + 'partialRootPaths' => [ + 'EXT:core/Resources/Private/Partials/', + 'EXT:backend/Resources/Private/Partials/', + ], + ], + ], + + 'user-defined global and local templates' => [ + 'globalConfig' => [ + 'templateRootPaths' => [ + 0 => 'EXT:core/Resources/Private/Templates/Email/', + 10 => 'EXT:backend/Resources/Private/Templates/Email/', + 20 => 'path/to/myextension/Resources/Private/Templates/Email/', + ], + 'layoutRootPaths' => [ + 0 => 'EXT:core/Resources/Private/Layouts/', + 10 => 'EXT:backend/Resources/Private/Layouts/', + 20 => 'path/to/myextension/Resources/Private/Layouts/Email/', + ], + 'partialRootPaths' => [ + 0 => 'EXT:core/Resources/Private/Partials/', + 10 => 'EXT:backend/Resources/Private/Partials/', + 20 => 'path/to/myextension/Resources/Private/Partials/Email/', + ], + ], + 'localConfig' => [ + 'templateRootPaths' => [ + 10 => 'EXT:form/Resources/Private/Frontend/Templates/Finishers/Email/', + 100 => 'path/to/myextension/Resources/Private/Templates/Form/Email/', + ], + 'layoutRootPaths' => [ + 100 => 'path/to/myextension/Resources/Private/Layouts/Form/Email/', + ], + 'partialRootPaths' => [ + 100 => 'path/to/myextension/Resources/Private/Partials/Form/Email/', + ], + ], + 'expected' => [ + 'templateRootPaths' => [ + 'EXT:core/Resources/Private/Templates/Email/', + 'EXT:form/Resources/Private/Frontend/Templates/Finishers/Email/', + 'path/to/myextension/Resources/Private/Templates/Email/', + 'path/to/myextension/Resources/Private/Templates/Form/Email/', + ], + 'layoutRootPaths' => [ + 'EXT:core/Resources/Private/Layouts/', + 'EXT:backend/Resources/Private/Layouts/', + 'path/to/myextension/Resources/Private/Layouts/Email/', + 'path/to/myextension/Resources/Private/Layouts/Form/Email/', + ], + 'partialRootPaths' => [ + 'EXT:core/Resources/Private/Partials/', + 'EXT:backend/Resources/Private/Partials/', + 'path/to/myextension/Resources/Private/Partials/Email/', + 'path/to/myextension/Resources/Private/Partials/Form/Email/', + ], + ], + ], + ]; + } + + #[Test] + #[DataProvider('templatePathsAreMergedCorrectlyDataProvider')] + public function templatePathsAreMergedCorrectly(array $globalConfig, array $localConfig, array $expected): void + { + $subject = $this->getAccessibleMock(EmailFinisher::class, null, [], '', false); + $templatePaths = $subject->_call('initializeTemplatePaths', $globalConfig, $localConfig); + + self::assertSame(array_map(fn($path) => GeneralUtility::getFileAbsFileName($path), $expected['templateRootPaths']), $templatePaths->getTemplateRootPaths()); + self::assertSame(array_map(fn($path) => GeneralUtility::getFileAbsFileName($path), $expected['layoutRootPaths']), $templatePaths->getLayoutRootPaths()); + self::assertSame(array_map(fn($path) => GeneralUtility::getFileAbsFileName($path), $expected['partialRootPaths']), $templatePaths->getPartialRootPaths()); + } +}