Skip to content

Commit

Permalink
[BUGFIX] Use RootLineUtility to resolve page template/configuration
Browse files Browse the repository at this point in the history
Avoids issues with root line breaking on first hidden/disabled
page and at the same time increases performance.

Close: #1898
  • Loading branch information
NamelessCoder committed Dec 5, 2021
1 parent d0e4db3 commit 86220d1
Show file tree
Hide file tree
Showing 4 changed files with 21 additions and 69 deletions.
18 changes: 3 additions & 15 deletions Classes/Provider/PageProvider.php
Expand Up @@ -16,6 +16,7 @@
use FluidTYPO3\Flux\Utility\RecursiveArrayUtility;
use TYPO3\CMS\Core\DataHandling\DataHandler;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\RootlineUtility;
use TYPO3\CMS\Extbase\Reflection\ObjectAccess;
use TYPO3\CMS\Fluid\View\TemplatePaths;

Expand Down Expand Up @@ -408,20 +409,7 @@ protected function getParentFieldValue(array $row)
*/
protected function loadRecordTreeFromDatabase($record)
{
$parentFieldName = $this->getParentFieldName($record);
if (false === isset($record[$parentFieldName])) {
$record[$parentFieldName] = $this->getParentFieldValue($record);
}
$records = [];
while (0 < $record[$parentFieldName]) {
$record = $this->recordService->getSingle($this->getTableName($record), '*', $record[$parentFieldName]);
if (!$record) {
break;
}
$parentFieldName = $this->getParentFieldName($record);
array_push($records, $record);
}
$records = array_reverse($records);
return $records;
$rootLineUtility = GeneralUtility::makeInstance(RootlineUtility::class, $record['uid']);
return array_slice($rootLineUtility->get(), 1);
}
}
39 changes: 13 additions & 26 deletions Classes/Service/PageService.php
Expand Up @@ -17,6 +17,7 @@
use TYPO3\CMS\Core\Log\LogManager;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\RootlineUtility;
use TYPO3\CMS\Extbase\Configuration\ConfigurationManagerInterface;
use TYPO3\CMS\Extbase\Object\ObjectManager;
use TYPO3\CMS\Fluid\View\TemplatePaths;
Expand Down Expand Up @@ -110,19 +111,12 @@ public function getPageTemplateConfiguration($pageUid)
if ($fromCache) {
return $fromCache;
}
$fieldList = 'tx_fed_page_controller_action_sub,t3ver_oid,pid,uid';
$page = $this->workspacesAwareRecordService->getSingle(
'pages',
'tx_fed_page_controller_action,' . $fieldList,
$pageUid
);
if (null === $page) {
return null;
}

$rootLineUtility = $this->getRootLineUtility($pageUid);

// Initialize with possibly-empty values and loop root line
// to fill values as they are detected.
do {
foreach ($rootLineUtility->get() as $page) {
$resolvedMainTemplateIdentity = is_array($page['tx_fed_page_controller_action']) ? $page['tx_fed_page_controller_action'][0] : $page['tx_fed_page_controller_action'];
$resolvedSubTemplateIdentity = is_array($page['tx_fed_page_controller_action_sub']) ? $page['tx_fed_page_controller_action_sub'][0] : $page['tx_fed_page_controller_action_sub'];
$containsSubDefinition = (false !== strpos($page['tx_fed_page_controller_action_sub'], '->'));
Expand All @@ -137,30 +131,18 @@ public function getPageTemplateConfiguration($pageUid)
}
break;
}
// Note: 't3ver_oid' is analysed in order to make versioned records inherit the original record's
// configuration as an emulated first parent page.
$resolveParentPageUid = $page['pid'];
// Avoid useless SQL query if uid is 0, because uids in the database start from 1.
if (0 === $resolveParentPageUid) {
break;
}
$page = $this->workspacesAwareRecordService->getSingle(
'pages',
$fieldList,
$resolveParentPageUid
);
} while (null !== $page);
};
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.
return null;
}
$configurarion = [
$configuration = [
'tx_fed_page_controller_action' => $resolvedMainTemplateIdentity,
'tx_fed_page_controller_action_sub' => $resolvedSubTemplateIdentity
];
$runtimeCache->set($cacheId, $configurarion);
return $configurarion;
$runtimeCache->set($cacheId, $configuration);
return $configuration;
}

/**
Expand Down Expand Up @@ -266,4 +248,9 @@ protected function getRuntimeCache()
{
return GeneralUtility::makeInstance(CacheManager::class)->getCache('cache_runtime');
}

protected function getRootLineUtility(int $pageUid): RootlineUtility
{
return GeneralUtility::makeInstance(RootlineUtility::class, $pageUid);
}
}
21 changes: 0 additions & 21 deletions Tests/Unit/Provider/PageProviderTest.php
Expand Up @@ -231,27 +231,6 @@ public function canGetFlexformValuesUnderInheritanceConditions()
$this->assertEquals($values, array());
}

/**
* @test
*/
public function canLoadRecordTreeFromDatabase()
{
$record = $this->getBasicRecord();
$provider = $this->getMockBuilder(
str_replace('Tests\\Unit\\', '', substr(get_class($this), 0, -4))
)->setMethods(
array('loadRecordFromDatabase', 'getParentFieldName', 'getParentFieldValue')
)->getMock();
$provider->expects($this->exactly(2))->method('getParentFieldName')->will($this->returnValue('somefield'));
$provider->expects($this->exactly(1))->method('getParentFieldValue')->will($this->returnValue(1));
$recordService = $this->getMockBuilder(WorkspacesAwareRecordService::class)->setMethods(['getSingle'])->getMock();
$recordService->expects($this->exactly(1))->method('getSingle')->will($this->returnValue($record));
$provider->injectRecordService($recordService);
$output = $this->callInaccessibleMethod($provider, 'loadRecordTreeFromDatabase', $record);
$expected = array($record);
$this->assertEquals($expected, $output);
}

/**
* @test
*/
Expand Down
12 changes: 5 additions & 7 deletions Tests/Unit/Service/PageServiceTest.php
Expand Up @@ -15,6 +15,7 @@
use FluidTYPO3\Flux\Tests\Unit\AbstractTestCase;
use TYPO3\CMS\Core\Utility\ExtensionManagementUtility;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\RootlineUtility;
use TYPO3\CMS\Extbase\Object\ObjectManager;

/**
Expand Down Expand Up @@ -55,13 +56,10 @@ public function getPageTemplateConfigurationWithZeroUidReturnsNull()
*/
public function testGetPageTemplateConfiguration(array $records, $expected)
{
/** @var WorkspacesAwareRecordService|\PHPUnit_Framework_MockObject_MockObject $service */
$service = $this->getMockBuilder(WorkspacesAwareRecordService::class)->setMethods(array('getSingle'))->getMock();
foreach ($records as $index => $record) {
$service->expects($this->at($index))->method('getSingle')->willReturn($record);
}
$instance = new PageService();
$instance->injectWorkspacesAwareRecordService($service);
$rootLineUtility = $this->getMockBuilder(RootlineUtility::class)->setMethods(['get'])->disableOriginalConstructor()->getMock();
$rootLineUtility->expects(self::once())->method('get')->willReturn($records);
$instance = $this->getMockBuilder(PageService::class)->setMethods(['getRootLineUtility'])->getMock();
$instance->expects(self::once())->method('getRootLineUtility')->willReturn($rootLineUtility);
$result = $instance->getPageTemplateConfiguration(1);
$this->assertEquals($expected, $result);
}
Expand Down

0 comments on commit 86220d1

Please sign in to comment.