Skip to content

Commit

Permalink
[BUGFIX] Mitigate unrelated page traversal for glossary lookup
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
NarkNiro committed Jun 7, 2024
1 parent 28e04b4 commit 9fa0a13
Showing 1 changed file with 27 additions and 12 deletions.
39 changes: 27 additions & 12 deletions Classes/Domain/Repository/GlossaryRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
Expand Down

0 comments on commit 9fa0a13

Please sign in to comment.