From 51cece220e4001e6165265d48a409f7d4cd14314 Mon Sep 17 00:00:00 2001 From: Christian Weiske Date: Fri, 29 Sep 2017 11:16:24 +0200 Subject: [PATCH] [BUGFIX] Support mixing of fluidpages with other backend layouts When mixing both fluidpages and templavoila page layouts, the page's backend_layout setting needs to be checked to make sure that fluidpages is responsible for handling the rendering. Resolves: https://github.com/FluidTYPO3/fluidpages/issues/366 --- Classes/Provider/PageProvider.php | 3 +- Classes/Service/PageService.php | 20 ++++- Tests/Unit/Provider/PageProviderTest.php | 79 ++++++++++++++++++- Tests/Unit/Service/PageServiceTest.php | 98 ++++++++++++++++++++++-- 4 files changed, 187 insertions(+), 13 deletions(-) diff --git a/Classes/Provider/PageProvider.php b/Classes/Provider/PageProvider.php index 58cda02f..01100a60 100644 --- a/Classes/Provider/PageProvider.php +++ b/Classes/Provider/PageProvider.php @@ -199,7 +199,8 @@ public function getControllerActionFromRecord(array $row) */ public function getControllerActionReferenceFromRecord(array $row) { - if (true === empty($row[self::FIELD_ACTION_MAIN])) { + $useFluidpages = substr($row['backend_layout'], 0, 12) == 'fluidpages__'; + if (true === empty($row[self::FIELD_ACTION_MAIN]) || false === $useFluidpages) { $row = $this->pageService->getPageTemplateConfiguration($row['uid']); } return $row[self::FIELD_ACTION_MAIN]; diff --git a/Classes/Service/PageService.php b/Classes/Service/PageService.php index 547ecfaa..cdfdb5c7 100755 --- a/Classes/Service/PageService.php +++ b/Classes/Service/PageService.php @@ -109,7 +109,7 @@ public function getPageTemplateConfiguration($pageUid) if ($fromCache) { return $fromCache; } - $fieldList = 'tx_fed_page_controller_action_sub,t3ver_oid,pid,uid'; + $fieldList = 'tx_fed_page_controller_action_sub,backend_layout,backend_layout_next_level,t3ver_oid,pid,uid'; $page = $this->workspacesAwareRecordService->getSingle( 'pages', 'tx_fed_page_controller_action,' . $fieldList, @@ -120,10 +120,13 @@ public function getPageTemplateConfiguration($pageUid) // to fill values as they are detected. $resolvedMainTemplateIdentity = $page['tx_fed_page_controller_action']; $resolvedSubTemplateIdentity = $page['tx_fed_page_controller_action_sub']; + $checkTemplates = true; + $resolvedUseFluidpages = substr($page['backend_layout'], 0, 12) == 'fluidpages__'; + $checkUseFluidpages = (false === $resolvedUseFluidpages); do { $containsSubDefinition = (false !== strpos($page['tx_fed_page_controller_action_sub'], '->')); $isCandidate = ((integer) $page['uid'] !== $pageUid); - if (true === $containsSubDefinition && true === $isCandidate) { + if (true == $checkTemplates && true === $containsSubDefinition && true === $isCandidate) { $resolvedSubTemplateIdentity = $page['tx_fed_page_controller_action_sub']; if (true === empty($resolvedMainTemplateIdentity)) { // Conditions met: current page is not $pageUid, original page did not @@ -131,6 +134,14 @@ public function getPageTemplateConfiguration($pageUid) // Then, set our "this page" value to use the "sub" selection that was detected. $resolvedMainTemplateIdentity = $resolvedSubTemplateIdentity; } + $checkTemplates = false; + } + $containsSubBackendLayout = !empty($page['backend_layout_next_level']); + if (true === $checkUseFluidpages && true === $isCandidate && true === $containsSubBackendLayout) { + $resolvedUseFluidpages = substr($page['backend_layout_next_level'], 0, 12) == 'fluidpages__'; + $checkUseFluidpages = false; + } + if (false === $checkTemplates && false === $checkUseFluidpages) { break; } // Note: 't3ver_oid' is analysed in order to make versioned records inherit the original record's @@ -142,6 +153,11 @@ public function getPageTemplateConfiguration($pageUid) $resolveParentPageUid ); } while (null !== $page); + + if (false === $resolvedUseFluidpages) { + // No "fluidpages' backend layout was configured for this page + return null; + } if (true === empty($resolvedMainTemplateIdentity) && true === empty($resolvedSubTemplateIdentity)) { // Neither directly configured "this page" nor inherited "sub" contains a valid value; // no configuration was detected at all. diff --git a/Tests/Unit/Provider/PageProviderTest.php b/Tests/Unit/Provider/PageProviderTest.php index bb6aa3a2..b6f91ecf 100644 --- a/Tests/Unit/Provider/PageProviderTest.php +++ b/Tests/Unit/Provider/PageProviderTest.php @@ -165,11 +165,86 @@ public function getControllerActionFromRecordTestValues() { return array( array(array('doktype' => PageControllerInterface::DOKTYPE_RAW), '', false, 'raw'), - array(array('doktype' => 0, 'tx_fed_page_controller_action' => ''), 'tx_fed_page_flexform', true, 'default'), - array(array('doktype' => 0, 'tx_fed_page_controller_action' => 'fluidpages->action'), 'tx_fed_page_flexform', false, 'action'), + array(array('doktype' => 0, 'backend_layout' => 'fluidpages__fluidpages', 'tx_fed_page_controller_action' => ''), 'tx_fed_page_flexform', true, 'default'), + array(array('doktype' => 0, 'backend_layout' => 'fluidpages__fluidpages', 'tx_fed_page_controller_action' => 'fluidpages->action'), 'tx_fed_page_flexform', false, 'action'), ); } + /** + * @dataProvider getControllerActionReferenceFromRecordTestValues + * + * @param array $record Page row + * @param mixed $calcRow Row data calculated by pageService->getPageTemplateConfiguration + * @param mixed $expected Expected return value + */ + public function testGetControllerActionReferenceFromRecord(array $record, $calcRow, $expected) + { + $instance = new PageProvider(); + /** @var PageService $service */ + $pageServiceMock = $this->getMockBuilder('FluidTYPO3\\Fluidpages\\Service\\PageService')->setMethods(array('getPageTemplateConfiguration'))->getMock(); + $pageServiceMock->expects($this->any()) + ->method('getPageTemplateConfiguration') + ->will($this->returnValue($calcRow)); + $instance->injectPageService($pageServiceMock); + + $result = $instance->getControllerActionReferenceFromRecord($record); + $this->assertEquals($expected, $result); + } + + /** + * Data provider for testGetControllerActionReferenceFromRecord() + * + * @return array + */ + public function getControllerActionReferenceFromRecordTestValues() + { + return [ + 'no action' => [ + [ + 'tx_fed_page_controller_action' => '', + ], + null, + null + ], + 'normal action' => [ + [ + 'tx_fed_page_controller_action' => 'test1->test1', + 'backend_layout' => 'fluidpages__foo', + ], + [], + 'test1->test1' + ], + 'no action, result from pageService' => [ + [ + 'tx_fed_page_controller_action' => '', + 'backend_layout' => 'fluidpages__bar', + ], + [ + 'tx_fed_page_controller_action' => 'test1->test1', + ], + 'test1->test1' + ], + 'no backend layout' => [ + [ + 'tx_fed_page_controller_action' => 'test1->test1', + 'backend_layout' => '', + ], + null, + null + ], + 'no backend layout, result from pageService' => [ + [ + 'tx_fed_page_controller_action' => 'test1->test1', + 'backend_layout' => '', + ], + [ + 'tx_fed_page_controller_action' => 'test2->test2' + ], + 'test2->test2' + ], + ]; + } + public function testGetFlexFormValuesReturnsCollectedDataWhenEncounteringNullForm() { $tree = array( diff --git a/Tests/Unit/Service/PageServiceTest.php b/Tests/Unit/Service/PageServiceTest.php index b11f99b2..f58bfa53 100644 --- a/Tests/Unit/Service/PageServiceTest.php +++ b/Tests/Unit/Service/PageServiceTest.php @@ -71,14 +71,96 @@ public function testGetPageTemplateConfiguration(array $records, $expected) */ public function getPageTemplateConfigurationTestValues() { - $m = 'tx_fed_page_controller_action'; - $s = 'tx_fed_page_controller_action_sub'; - return array( - array(array(array()), null), - array(array(array($m => '', $s => '')), null), - array(array(array($m => 'test1->test1', $s => 'test2->test2')), array($m => 'test1->test1', $s => 'test2->test2')), - array(array(array($m => ''), array($s => 'test2->test2')), array($m => 'test2->test2', $s => 'test2->test2')) - ); + $b = 'backend_layout'; + $bs = 'backend_layout_next_level'; + $a = 'tx_fed_page_controller_action'; + $as = 'tx_fed_page_controller_action_sub'; + $bfp = 'fluidpages__fluidpages'; + return [ + 'no data at all' => [ + [[]], + null + ], + 'empty actions' => [ + [ + [$a => '', $as => '', $b => $bfp, $bs => $bfp] + ], + null + ], + 'controller action on page itself' => [ + [ + [$a => 'test1->test1', $as => 'test2->test2', $b => $bfp, $bs => $bfp] + ], + [$a => 'test1->test1', $as => 'test2->test2'] + ], + 'sub controller action on parent page' => [ + [ + //pages are listed in reverse order, root level last + [$a => '', $b => $bfp, $bs => $bfp], + [$as => 'test2->test2', $b => $bfp, $bs => $bfp] + ], + [$a => 'test2->test2', $as => 'test2->test2'] + ], + 'no backend layout configured' => [ + [ + [$a => 'test1->test1', $as => 'test2->test2', $b => '', $bs => ''], + ], + null + ], + 'backend layout configured only for parent page' => [ + [ + [$a => 'test1->test1', $as => 'test2->test2', $b => '' , $bs => ''], + [$a => 'test1->test1', $as => 'test2->test2', $b => $bfp, $bs => ''], + ], + null + ], + 'backend layout configured on parent page' => [ + [ + [$a => 'test1->test1', $as => 'test2->test2', $b => '', $bs => ''], + [$a => 'test1->test1', $as => 'test2->test2', $b => '', $bs => $bfp], + ], + [$a => 'test1->test1', $as => 'test2->test2'], + ], + 'backend layout configured on parent page #2' => [ + [ + [$a => '' , $as => '' , $b => '', $bs => ''], + [$a => 'test1->test1', $as => 'test2->test2', $b => '', $bs => $bfp], + ], + [$a => 'test2->test2', $as => 'test2->test2'], + ], + 'different backend layout in between' => [ + [ + [$a => '' , $as => '' , $b => '', $bs => ''], + [$a => '' , $as => '' , $b => '', $bs => 'templavoila'], + [$a => 'test1->test1', $as => 'test2->test2', $b => '', $bs => $bfp], + ], + null + ], + 'self backend layout, but different backend layout in between' => [ + [ + [$a => '' , $as => '' , $b => $bfp, $bs => ''], + [$a => '' , $as => '' , $b => '', $bs => 'templavoila'], + [$a => 'test1->test1', $as => 'test2->test2', $b => '', $bs => $bfp], + ], + [$a => 'test2->test2', $as => 'test2->test2'] + ], + 'action and backend layout on different levels: action higher' => [ + [ + [$a => '' , $as => '' , $b => '', $bs => ''], + [$a => '' , $as => '' , $b => '', $bs => $bfp], + [$a => 'test1->test1', $as => 'test2->test2', $b => '', $bs => ''], + ], + [$a => 'test2->test2', $as => 'test2->test2'] + ], + 'action and backend layout on different levels: backend layout higher' => [ + [ + [$a => '' , $as => '' , $b => '', $bs => ''], + [$a => 'test1->test1', $as => 'test2->test2', $b => '', $bs => ''], + [$a => '' , $as => '' , $b => '', $bs => $bfp], + ], + [$a => 'test2->test2', $as => 'test2->test2'] + ], + ]; } /**