--- a/Configuration/DefaultConfiguration.php 2023-04-11 15:10:15 +++ b/Configuration/DefaultConfiguration.php 2023-04-13 11:34:53 @@ -198,6 +198,15 @@ ], 'groups' => ['pages'] ], + 'pagecandidate' => [ + 'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class, + 'backend' => \TYPO3\CMS\Core\Cache\Backend\Typo3DatabaseBackend::class, + 'options' => [ + 'compression' => true, + 'defaultLifetime' => 2592000, // 30 days; set this to a lower value in case your cache gets too big + ], + 'groups' => ['pages'] + ], 'runtime' => [ 'frontend' => \TYPO3\CMS\Core\Cache\Frontend\VariableFrontend::class, 'backend' => \TYPO3\CMS\Core\Cache\Backend\TransientMemoryBackend::class, --- a/Classes/Routing/PageSlugCandidateProvider.php 2023-04-13 09:40:15 +++ b/Classes/Routing/PageSlugCandidateProvider.php 2023-04-13 10:03:15 @@ -18,6 +18,7 @@ namespace TYPO3\CMS\Core\Routing; use Doctrine\DBAL\Connection; +use TYPO3\CMS\Core\Cache\CacheManager; use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Database\Query\Restriction\DeletedRestriction; @@ -197,6 +198,19 @@ $languages = [$languageId]; } $searchLiveRecordsOnly = $this->context->getPropertyFromAspect('workspace', 'isLive'); + $cache = GeneralUtility::makeInstance(CacheManager::class)->getCache('pagecandidate'); + $cacheIdentifier = sha1(json_encode([ + $this->site->getIdentifier(), + $searchLiveRecordsOnly, + $slugCandidates, + $languageId, + $excludeUids, + $languages + ])); + $pages = $cache->get($cacheIdentifier); + if ($pages !== false) { + return $pages; + } $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable('pages'); $queryBuilder @@ -330,6 +344,13 @@ } } } + $cacheKeys = array_map( + function (int $uid) { + return 'pages_' . $uid; + }, + array_column($pages, 'uid') + ); + $cache->set($cacheIdentifier, $pages, $cacheKeys); return $pages; }