Skip to content

Commit b51c348

Browse files
susannemoogbmack
authored andcommitted
[BUGFIX] Check rootline for extendToSubpages when previewing
The rootline may contain extendToSubpages settings for hidden or timed records which prevented previewing a page because the preview checks only considered the current page. The rootline is now taken into account. Resolves: #17599 Releases: main, 12.4 Change-Id: I0271caf8decd46fd9dedf31158d62a86e1e0028c Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/79656 Tested-by: Frank N�gler <frank.naegler@typo3.com> Tested-by: Benni Mack <benni@typo3.org> Tested-by: core-ci <typo3@b13.com> Reviewed-by: Benni Mack <benni@typo3.org> Reviewed-by: Frank N�gler <frank.naegler@typo3.com>
1 parent aa956a5 commit b51c348

File tree

1 file changed

+45
-2
lines changed

1 file changed

+45
-2
lines changed

typo3/sysext/frontend/Classes/Middleware/PreviewSimulator.php

Lines changed: 45 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,13 +21,15 @@
2121
use Psr\Http\Message\ServerRequestInterface;
2222
use Psr\Http\Server\MiddlewareInterface;
2323
use Psr\Http\Server\RequestHandlerInterface;
24+
use TYPO3\CMS\Core\Cache\CacheManager;
2425
use TYPO3\CMS\Core\Context\Context;
2526
use TYPO3\CMS\Core\Context\DateTimeAspect;
2627
use TYPO3\CMS\Core\Context\LanguageAspectFactory;
2728
use TYPO3\CMS\Core\Context\VisibilityAspect;
2829
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
2930
use TYPO3\CMS\Core\Routing\PageArguments;
3031
use TYPO3\CMS\Core\Utility\GeneralUtility;
32+
use TYPO3\CMS\Core\Utility\RootlineUtility;
3133
use TYPO3\CMS\Frontend\Aspect\PreviewAspect;
3234
use TYPO3\CMS\Frontend\Controller\ErrorController;
3335
use TYPO3\CMS\Frontend\Page\PageAccessFailureReasons;
@@ -66,19 +68,20 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
6668
}
6769
// The preview flag is set if the current page turns out to be hidden
6870
$showHiddenPages = $this->checkIfPageIsHidden($pageArguments->getPageId(), $request);
71+
$rootlineRequiresPreviewFlag = $this->checkIfRootlineRequiresPreview($pageArguments->getPageId());
6972
$simulatingDate = $this->simulateDate($request);
7073
$simulatingGroup = $this->simulateUserGroup($request);
7174
$showHiddenRecords = $visibilityAspect->includeHidden();
7275
$isOfflineWorkspace = $this->context->getPropertyFromAspect('workspace', 'id', 0) > 0;
73-
$isPreview = $simulatingDate || $simulatingGroup || $showHiddenRecords || $showHiddenPages || $isOfflineWorkspace;
76+
$isPreview = $simulatingDate || $simulatingGroup || $showHiddenRecords || $showHiddenPages || $isOfflineWorkspace || $rootlineRequiresPreviewFlag;
7477
if ($this->context->hasAspect('frontend.preview')) {
7578
$previewAspect = $this->context->getAspect('frontend.preview');
7679
$isPreview = $previewAspect->isPreview() || $isPreview;
7780
}
7881
$previewAspect = GeneralUtility::makeInstance(PreviewAspect::class, $isPreview);
7982
$this->context->setAspect('frontend.preview', $previewAspect);
8083

81-
if ($showHiddenPages) {
84+
if ($showHiddenPages || $rootlineRequiresPreviewFlag) {
8285
$newAspect = GeneralUtility::makeInstance(VisibilityAspect::class, true, $visibilityAspect->includeHiddenContent(), $visibilityAspect->includeDeletedRecords());
8386
$this->context->setAspect('visibility', $newAspect);
8487
}
@@ -87,6 +90,46 @@ public function process(ServerRequestInterface $request, RequestHandlerInterface
8790
return $handler->handle($request);
8891
}
8992

93+
protected function checkIfRootlineRequiresPreview(int $pageId): bool
94+
{
95+
$rootlineUtility = GeneralUtility::makeInstance(RootlineUtility::class, $pageId, '', $this->context);
96+
$pageRepository = GeneralUtility::makeInstance(PageRepository::class, $this->context);
97+
$groupRestricted = false;
98+
$timeRestricted = false;
99+
$hidden = false;
100+
try {
101+
$rootLine = $rootlineUtility->get();
102+
$pageInfo = $pageRepository->getPage_noCheck($pageId);
103+
// Only check rootline if the current page has not set extendToSubpages itself
104+
// @see \TYPO3\CMS\Backend\Routing\PreviewUriBuilder::class
105+
if (!(bool)($pageInfo['extendToSubpages'] ?? false)) {
106+
// remove the current page from the rootline
107+
array_shift($rootLine);
108+
foreach ($rootLine as $page) {
109+
// Skip root node and pages which do not define extendToSubpages
110+
if ((int)($page['uid'] ?? 0) === 0 || !(bool)($page['extendToSubpages'] ?? false)) {
111+
continue;
112+
}
113+
$groupRestricted = (bool)(string)($page['fe_group'] ?? '');
114+
$timeRestricted = (int)($page['starttime'] ?? 0) || (int)($page['endtime'] ?? 0);
115+
$hidden = (int)($page['hidden'] ?? 0);
116+
// Stop as soon as a page in the rootline has extendToSubpages set
117+
break;
118+
}
119+
}
120+
121+
} catch (\Exception) {
122+
// if the rootline cannot be resolved (404 because of delete placeholder in workspaces for example)
123+
// we do not want to fail here but rather continue handling the request to trigger the TSFE 404 handling
124+
} finally {
125+
// clear the rootline cache to ensure it's cleanly built with the full context later on.
126+
$cacheManager = GeneralUtility::makeInstance(CacheManager::class);
127+
$cacheManager->getCache('runtime')->flushByTag(RootlineUtility::RUNTIME_CACHE_TAG);
128+
$cacheManager->getCache('rootline')->flush();
129+
}
130+
return $groupRestricted || $timeRestricted || $hidden;
131+
}
132+
90133
/**
91134
* Checks if the page is hidden in the active workspace + language setup.
92135
*/

0 commit comments

Comments
 (0)