From 9fa0a13e8cd60b411096495553f861d8c1f8b443 Mon Sep 17 00:00:00 2001 From: Mark Date: Fri, 7 Jun 2024 15:21:09 +0200 Subject: [PATCH] [BUGFIX] Mitigate unrelated page traversal for glossary lookup Based on the concept the matching glossaries for the current site root tree should be used for translation process. Glossaries are managed on default pages with the `glossaries` module attached, thus are free to be defined within the page tree structure. Using a page traversal approach from the detected site root becomes really costly as it traverse the full page tree beneath the matched site root, thus becoming quickly quite costly. Albeit not the best approach, retrieving pages with the module attached and using the SiteFinder and therefore the rootline to sort out module pages not included for the site root reduces the traversed and retrieved pages white a lot. Note: With dropping TYPO3 v12 support it would be possible to use handcrafted common table expressions to further optimize that lookup and with TYPO3 v13 at least TYPO3 Core internal API may be available. This change modifies the glossary id lookup method to exchange the pagetraversal approach with a flat record list rootline check approach as a first, quick and non breaking improvement. Instances not using the glossary feature avoids the recursive traversal at all with this implementation. --- .../Domain/Repository/GlossaryRepository.php | 39 +++++++++++++------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/Classes/Domain/Repository/GlossaryRepository.php b/Classes/Domain/Repository/GlossaryRepository.php index fbef837c..6256f902 100644 --- a/Classes/Domain/Repository/GlossaryRepository.php +++ b/Classes/Domain/Repository/GlossaryRepository.php @@ -11,6 +11,7 @@ use TYPO3\CMS\Backend\Utility\BackendUtility; use TYPO3\CMS\Core\Database\Connection; use TYPO3\CMS\Core\Database\ConnectionPool; +use TYPO3\CMS\Core\Domain\Repository\PageRepository; use TYPO3\CMS\Core\Exception\SiteNotFoundException; use TYPO3\CMS\Core\Site\Entity\Site; use TYPO3\CMS\Core\Site\SiteFinder; @@ -470,33 +471,47 @@ private function getGlossary( */ private function getGlossariesInRootByCurrentPage(int $pageId): array { - $site = GeneralUtility::makeInstance(SiteFinder::class) - ->getSiteByPageId($pageId); - $rootPage = $site->getRootPageId(); - $allPages = GeneralUtility::makeInstance(PageTreeRepository::class) - ->getTreeList($rootPage, 999); $db = GeneralUtility::makeInstance(ConnectionPool::class) ->getQueryBuilderForTable('pages'); - $statement = $db + + $result = $db ->select('uid') ->from('pages') ->where( - $db->expr()->in('uid', $allPages), - $db->expr()->eq('doktype', $db->createNamedParameter(254, Connection::PARAM_INT)), + $db->expr()->eq( + 'doktype', + $db->createNamedParameter( + PageRepository::DOKTYPE_SYSFOLDER, + Connection::PARAM_INT + ) + ), $db->expr()->eq('module', $db->createNamedParameter('glossary')) - ); - $result = $statement->executeQuery()->fetchAllAssociative(); + )->executeQuery(); - if (!is_array($result)) { + if ($result->rowCount() === 0) { return []; } + + $rootPage = $this->findRootPageId($pageId); + $ids = []; - foreach ($result as $row) { + foreach ($result->fetchAllAssociative() as $row) { + $glossaryRootPageID = $this->findRootPageId($row['uid']); + if ($glossaryRootPageID !== $rootPage) { + continue; + } + $ids[] = $row['uid']; } return $ids; } + private function findRootPageId(int $pageId): int + { + $site = GeneralUtility::makeInstance(SiteFinder::class)->getSiteByPageId($pageId); + return $site->getRootPageId(); + } + public function setGlossaryNotSyncOnPage(int $pageId): void { $queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)