diff --git a/typo3/sysext/fluid/Classes/View/TemplatePaths.php b/typo3/sysext/fluid/Classes/View/TemplatePaths.php index c60de99d4f2609f4f2f48e357887fb90837c8aba..6bf132975d534374dd13ea35a699a82ebb42ba52 100644 --- a/typo3/sysext/fluid/Classes/View/TemplatePaths.php +++ b/typo3/sysext/fluid/Classes/View/TemplatePaths.php @@ -100,7 +100,11 @@ class TemplatePaths extends \TYPO3Fluid\Fluid\View\TemplatePaths foreach ($paths as $name => $defaultPaths) { if (!empty($configuredPaths[$name])) { - $paths[$name] = array_merge($defaultPaths, ArrayUtility::sortArrayWithIntegerKeys((array)$configuredPaths[$name])); + $configured = ArrayUtility::sortArrayWithIntegerKeys((array)$configuredPaths[$name]); + // calculate implicit default paths which have not been explicitly configured + $implicitDefaultPaths = array_diff($defaultPaths, $configured); + // prepend implicit default paths (which have not been found in configured paths), as fallbacks + $paths[$name] = array_merge($implicitDefaultPaths, $configured); } } diff --git a/typo3/sysext/fluid/Tests/Unit/View/TemplatePathsTest.php b/typo3/sysext/fluid/Tests/Unit/View/TemplatePathsTest.php index 30c1b47bad4e850664afd875d8c0b9c98c355b20..717339658d3a37ec2c0aa7e07b1a9e7011b9e31d 100644 --- a/typo3/sysext/fluid/Tests/Unit/View/TemplatePathsTest.php +++ b/typo3/sysext/fluid/Tests/Unit/View/TemplatePathsTest.php @@ -258,4 +258,52 @@ final class TemplatePathsTest extends UnitTestCase ], ], $result); } + + /** + * @test + */ + public function getContextSpecificViewConfigurationRespectsTypoScriptConfiguredPaths(): void + { + $configurationManager = $this->createMock(ConfigurationManagerInterface::class); + $configurationManager->expects(self::once())->method('getConfiguration')->willReturn([ + 'plugin.' => [ + 'tx_test.' => [ + 'view.' => [ + 'templateRootPaths.' => [ + '0' => 'base/Templates/', + '10' => 'test/Templates/', + ], + 'partialRootPaths.' => [ + '0' => 'base/Partials/', + '10' => 'test/Partials/', + ], + 'layoutRootPaths.' => [ + '0' => 'base/Layouts/', + '10' => 'test/Layouts/', + ], + ], + ], + ], + ]); + $subject = $this->getAccessibleMock(TemplatePaths::class, ['getConfigurationManager', 'getExtensionPrivateResourcesPath', 'isBackendMode', 'isFrontendMode']); + $subject->expects(self::once())->method('getExtensionPrivateResourcesPath')->with('test')->willReturn('test/'); + $subject->expects(self::once())->method('getConfigurationManager')->willReturn($configurationManager); + $subject->expects(self::once())->method('isBackendMode')->willReturn(false); + $subject->expects(self::once())->method('isFrontendMode')->willReturn(true); + $result = $subject->_call('getContextSpecificViewConfiguration', 'test'); + self::assertSame([ + 'templateRootPaths' => [ + 'base/Templates/', + 'test/Templates/', + ], + 'partialRootPaths' => [ + 'base/Partials/', + 'test/Partials/', + ], + 'layoutRootPaths' => [ + 'base/Layouts/', + 'test/Layouts/', + ], + ], $result); + } }