diff --git a/Build/phpstan11.neon b/Build/phpstan11.neon index a3f7c42..8bf0294 100644 --- a/Build/phpstan11.neon +++ b/Build/phpstan11.neon @@ -10,3 +10,9 @@ parameters: - message: '#Cannot call method getLanguageCode\(\) on string.#' path: %currentWorkingDirectory%/Classes/Compiler/LanguageMenuCompiler.php + - + message: '#Class TYPO3\\CMS\\Frontend\\Cache\\CacheLifetimeCalculator not found.#' + path: %currentWorkingDirectory%/Classes/CacheHelper.php + - + message: '#.*unknown class TYPO3\\CMS\\Core\\TypoScript\\FrontendTypoScript.#' + path: %currentWorkingDirectory%/Classes/CacheHelper.php diff --git a/Build/phpstan12.neon b/Build/phpstan12.neon index be8b22c..e8f1027 100644 --- a/Build/phpstan12.neon +++ b/Build/phpstan12.neon @@ -13,3 +13,6 @@ parameters: - message: '#Property TYPO3\\CMS\\Frontend\\Controller\\TypoScriptFrontendController::\$id \(int\) does not accept string.#' path: %currentWorkingDirectory%/Tests/Functional/Compiler/LanguageMenuCompilerTest.php + - + message: '#Call to an undefined method TYPO3\\CMS\\Core\\TypoScript\\FrontendTypoScript::getConfigArray\(\).#' + path: %currentWorkingDirectory%/Classes/CacheHelper.php diff --git a/Build/phpstan13.neon b/Build/phpstan13.neon index 95a99a3..e396ce1 100644 --- a/Build/phpstan13.neon +++ b/Build/phpstan13.neon @@ -16,6 +16,9 @@ parameters: - message: '#Access to undefined constant TYPO3\\CMS\\Core\\Domain\\Repository\\PageRepository::DOKTYPE_RECYCLER.#' path: %currentWorkingDirectory%/Tests/Unit/Domain/Repository/MenuRepositoryTest.php + - + message: '#.*get_cache_timeout\(\).*#' + path: %currentWorkingDirectory%/Classes/CacheHelper.php - message: '#Call to an undefined static method TYPO3\\CMS\\Frontend\\ContentObject\\AbstractContentObject::__construct\(\).#' path: %currentWorkingDirectory%/Classes/ContentObject/* diff --git a/Classes/CacheHelper.php b/Classes/CacheHelper.php index bc396f8..4fedd6e 100644 --- a/Classes/CacheHelper.php +++ b/Classes/CacheHelper.php @@ -11,10 +11,15 @@ * of the License, or any later version. */ +use Psr\Http\Message\ServerRequestInterface; use TYPO3\CMS\Core\Cache\Frontend\FrontendInterface; use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\Context\Exception\AspectNotFoundException; +use TYPO3\CMS\Core\Information\Typo3Version; use TYPO3\CMS\Core\SingletonInterface; +use TYPO3\CMS\Core\TypoScript\FrontendTypoScript; +use TYPO3\CMS\Core\Utility\GeneralUtility; +use TYPO3\CMS\Frontend\Cache\CacheLifetimeCalculator; use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController; /** @@ -27,9 +32,11 @@ class CacheHelper implements SingletonInterface { protected FrontendInterface $cache; protected bool $disableCaching = false; + protected Context $context; public function __construct(FrontendInterface $cache, Context $context) { + $this->context = $context; $this->cache = $cache; try { $this->disableCaching = $context->getPropertyFromAspect('workspace', 'id', 0) > 0; @@ -63,8 +70,8 @@ public function get(string $cacheIdentifier, callable $loader): array // Calculate tags + lifetime $tags = $this->buildTagsAndAddThemToPageCache($pages); - //$maximumLifeTime = $this->getMaxLifetimeOfPages($pages, $this->getFrontendController()->get_cache_timeout()); - $maximumLifeTime = 3454; + $defaultMaxLifeTime = $this->getDefaultMaxLifeTime(); + $maximumLifeTime = $this->getMaxLifetimeOfPages($pages, $defaultMaxLifeTime); $this->cache->set($cacheIdentifier, $pages, $tags, $maximumLifeTime); return $pages; } @@ -109,15 +116,58 @@ protected function getAllPageIdsFromItems(array $pages): array return $pageIds; } + protected function getDefaultMaxLifeTime(): int + { + if (GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion() < 13) { + $maxLifetime = (int)$this->getFrontendController()->get_cache_timeout(); + } else { + $request = $this->getServerRequest(); + $pageInformation = $request->getAttribute('frontend.page.information'); + /** @var ?FrontendTypoScript $typoScript */ + $typoScript = $request->getAttribute('frontend.typoscript'); + if ($typoScript === null || $pageInformation === null) { + return 0; + } + $typoScriptConfigArray = $typoScript->getConfigArray(); + $maxLifetime = GeneralUtility::makeInstance(CacheLifetimeCalculator::class) + ->calculateLifetimeForPage( + $pageInformation->getId(), + $pageInformation->getPageRecord(), + $typoScriptConfigArray, + 0, + $this->context + ); + } + return $maxLifetime; + } + /** * pages.cache_timeout is not used here, as this is supposed to be relevant for content of a page, not the * metadata. */ - protected function getMaxLifetimeOfPages(array $pages, int $maxLifetime = null): ?int + protected function getMaxLifetimeOfPages(array $pages, int $maxLifetime): int { foreach ($pages as $page) { if (!empty($page['endtime'])) { - $maxLifetimeOfPage = $page['endtime'] - $GLOBALS['EXEC_TIME']; + $maxLifetimeOfPage = (int)$page['endtime'] - $GLOBALS['EXEC_TIME']; + if (GeneralUtility::makeInstance(Typo3Version::class)->getMajorVersion() === 13) { + $request = $this->getServerRequest(); + /** @var ?FrontendTypoScript $typoScript */ + $typoScript = $request->getAttribute('frontend.typoscript'); + if ($typoScript === null) { + $typoScriptConfigArray = []; + } else { + $typoScriptConfigArray = $typoScript->getConfigArray(); + } + $maxLifetimeOfPage = GeneralUtility::makeInstance(CacheLifetimeCalculator::class) + ->calculateLifetimeForPage( + $page['uid'], + $page, + $typoScriptConfigArray, + 0, + $this->context + ); + } if ($maxLifetimeOfPage < $maxLifetime) { $maxLifetime = $maxLifetimeOfPage; } @@ -129,6 +179,11 @@ protected function getMaxLifetimeOfPages(array $pages, int $maxLifetime = null): return $maxLifetime; } + protected function getServerRequest(): ServerRequestInterface + { + return $GLOBALS['TYPO3_REQUEST']; + } + protected function getFrontendController(): TypoScriptFrontendController { return $GLOBALS['TSFE'];