diff --git a/typo3/sysext/fluid/Classes/View/TemplatePaths.php b/typo3/sysext/fluid/Classes/View/TemplatePaths.php index ebd8d46fb2eeac5d8fb5fcf6a0ed07df3891ef0d..3dd19a12cd779764a26869c4db2b281034f5e083 100644 --- a/typo3/sysext/fluid/Classes/View/TemplatePaths.php +++ b/typo3/sysext/fluid/Classes/View/TemplatePaths.php @@ -108,9 +108,9 @@ class TemplatePaths extends \TYPO3Fluid\Fluid\View\TemplatePaths ); } $signature = str_replace('_', '', $extensionKey); - if (TYPO3_MODE === 'BE' && isset($this->typoScript['module']['tx_' . $signature]['view'])) { + if ($this->isBackendMode() && isset($this->typoScript['module']['tx_' . $signature]['view'])) { $configuredPaths = (array)$this->typoScript['module']['tx_' . $signature]['view']; - } elseif (TYPO3_MODE === 'FE' && isset($this->typoScript['plugin']['tx_' . $signature]['view'])) { + } elseif (isset($this->typoScript['plugin']['tx_' . $signature]['view'])) { $configuredPaths = (array)$this->typoScript['plugin']['tx_' . $signature]['view']; } } @@ -121,7 +121,7 @@ class TemplatePaths extends \TYPO3Fluid\Fluid\View\TemplatePaths foreach ($paths as $name => $defaultPaths) { if (!empty($configuredPaths[$name])) { - $paths[$name] = array_merge($defaultPaths, (array)$configuredPaths[$name]); + $paths[$name] = array_merge($defaultPaths, ArrayUtility::sortArrayWithIntegerKeys((array)$configuredPaths[$name])); } } @@ -130,38 +130,6 @@ class TemplatePaths extends \TYPO3Fluid\Fluid\View\TemplatePaths return $paths; } - /** - * @return VariableFrontend - */ - protected function getRuntimeCache() - { - return GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_runtime'); - } - - /** - * Guarantees that $reference is turned into a - * correct, absolute path. The input can be a - * relative path or a FILE: or EXT: reference - * but cannot be a FAL resource identifier. - * - * @param mixed $reference - * @return string - */ - protected function ensureAbsolutePath($reference) - { - if (false === is_array($reference)) { - $filename = PathUtility::isAbsolutePath($reference) ? $reference : GeneralUtility::getFileAbsFileName($reference); - } else { - foreach ($reference as &$subValue) { - $subValue = $this->ensureAbsolutePath($subValue); - } - - return $reference; - } - - return $filename; - } - /** * Fills the path arrays with defaults, by package name. * Reads those defaults from TypoScript if possible and @@ -231,4 +199,40 @@ class TemplatePaths extends \TYPO3Fluid\Fluid\View\TemplatePaths { return $this->templatePathAndFilename; } + + /** + * Guarantees that $reference is turned into a + * correct, absolute path. The input can be a + * relative path or a FILE: or EXT: reference + * but cannot be a FAL resource identifier. + * + * @param mixed $reference + * @return string + */ + protected function ensureAbsolutePath($reference) + { + if (!is_array($reference)) { + return PathUtility::isAbsolutePath($reference) ? $reference : GeneralUtility::getFileAbsFileName($reference); + } + foreach ($reference as &$subValue) { + $subValue = $this->ensureAbsolutePath($subValue); + } + return $reference; + } + + /** + * @return bool + */ + protected function isBackendMode() + { + return TYPO3_MODE === 'BE'; + } + + /** + * @return VariableFrontend + */ + protected function getRuntimeCache() + { + return GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_runtime'); + } } diff --git a/typo3/sysext/fluid/Tests/Unit/View/TemplatePathsTest.php b/typo3/sysext/fluid/Tests/Unit/View/TemplatePathsTest.php index f6a598ae71dc0a5114a4f05827e26ee83d66778b..5c110460ed4a9a414b0e8eceac798ff12814fae0 100644 --- a/typo3/sysext/fluid/Tests/Unit/View/TemplatePathsTest.php +++ b/typo3/sysext/fluid/Tests/Unit/View/TemplatePathsTest.php @@ -14,6 +14,8 @@ namespace TYPO3\CMS\Fluid\Tests\Unit\View; * The TYPO3 project - inspiring people to share! */ +use TYPO3\CMS\Core\Cache\Frontend\VariableFrontend; +use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface; use TYPO3\CMS\Fluid\View\TemplatePaths; /** @@ -98,4 +100,64 @@ class TemplatePathsTest extends \TYPO3\TestingFramework\Core\Unit\UnitTestCase $subject->$setter($paths); $this->assertAttributeSame($expected, $method, $subject); } + + /** + * @test + */ + public function getContextSpecificViewConfigurationSortsTypoScriptConfiguredPathsCorrectly() + { + $configurationManager = $this->getMockBuilder(ConfigurationManagerInterface::class)->getMockForAbstractClass(); + $configurationManager->expects($this->once())->method('getConfiguration')->willReturn([ + 'plugin.' => [ + 'tx_test.' => [ + 'view.' => [ + 'templateRootPaths.' => [ + '30' => 'third', + '10' => 'first', + '20' => 'second' + ], + 'partialRootPaths.' => [ + '20' => '2', + '30' => '3', + '10' => '1' + ], + 'layoutRootPaths.' => [ + '130' => '3.', + '10' => '1.', + '120' => '2.' + ], + ] + ] + ] + ]); + $cache = $this->getMockBuilder(VariableFrontend::class)->setMethods(['get', 'set'])->disableOriginalConstructor()->getMock(); + $cache->expects($this->once())->method('get')->willReturn(false); + $cache->expects($this->once())->method('set'); + $subject = $this->getMockBuilder(TemplatePaths::class)->setMethods(['getConfigurationManager', 'getExtensionPrivateResourcesPath', 'getRuntimeCache', 'isBackendMode'])->getMock(); + $subject->expects($this->once())->method('getExtensionPrivateResourcesPath')->with('test')->willReturn('test/'); + $subject->expects($this->once())->method('getConfigurationManager')->willReturn($configurationManager); + $subject->expects($this->once())->method('getRuntimeCache')->willReturn($cache); + $subject->expects($this->once())->method('isBackendMode')->willReturn(false); + $result = $this->callInaccessibleMethod($subject, 'getContextSpecificViewConfiguration', 'test'); + $this->assertSame([ + 'templateRootPaths' => [ + 'test/Templates/', + 'first', + 'second', + 'third' + ], + 'partialRootPaths' => [ + 'test/Partials/', + '1', + '2', + '3' + ], + 'layoutRootPaths' => [ + 'test/Layouts/', + '1.', + '2.', + '3.' + ] + ], $result); + } }