Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 61 additions & 5 deletions Classes/System/Records/SystemTemplate/SystemTemplateRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
namespace ApacheSolrForTypo3\Solr\System\Records\SystemTemplate;

use ApacheSolrForTypo3\Solr\System\Records\AbstractRepository;
use Doctrine\DBAL\ArrayParameterType;
use Doctrine\DBAL\Exception as DBALException;

/**
Expand All @@ -34,23 +35,78 @@ class SystemTemplateRepository extends AbstractRepository
* @throws DBALException
*/
public function findOneClosestPageIdWithActiveTemplateByRootLine(array $rootLine): ?int
{
if (empty($rootLine)) {
return null;
}

[$rootLinePageIds, $rootLinePositions] = $this->extractPageIdsAndPositions($rootLine);
$templateRecords = $this->getTemplateRecordsFromRootlinePages($rootLinePageIds);

if (empty($templateRecords)) {
return null;
}

$this->sortTemplateRecordsByPageRootlinePosition($templateRecords, $rootLinePositions);

return isset($templateRecords[0]['pid']) ? (int)$templateRecords[0]['pid'] : null;
}

/**
* @param array<int, array{uid: int}> $rootLine
* @return array{0: list<int>, 1: array<int, int>}
*/
protected function extractPageIdsAndPositions(array $rootLine): array
{
$rootLinePageIds = [0];
foreach ($rootLine as $rootLineItem) {
$rootLinePageIds[] = (int)$rootLineItem['uid'];
$rootLinePositions = [];

foreach ($rootLine as $position => $rootLineItem) {
$pageId = (int)$rootLineItem['uid'];
$rootLinePageIds[] = $pageId;
$rootLinePositions[$pageId] = $position;
}

return [$rootLinePageIds, $rootLinePositions];
}

/**
* Retrieves template records associated with the given page IDs from the rootline.
*
* @param list<int> $rootLinePageIds The page IDs from the rootline to search for templates on.
* @return list<array{uid: int, pid: int}> A list of template records (uid, pid) found, or an empty list if none are found.
* @throws DBALException
*/
protected function getTemplateRecordsFromRootlinePages(array $rootLinePageIds): array
{
$queryBuilder = $this->getQueryBuilder();

$result = $queryBuilder
->select('uid', 'pid')
->from($this->table)
->where(
$queryBuilder->expr()->in('pid', $rootLinePageIds)
$queryBuilder->expr()->in(
'pid',
$queryBuilder->createNamedParameter(
$rootLinePageIds,
ArrayParameterType::INTEGER
)
)
)
->executeQuery()
->fetchAssociative();
->fetchAllAssociative();

return $result['pid'] ?? null;
return $result ?: [];
}

/**
* Sorts template records based on the rootline position of the page they belong to.
*
* @param list<array{uid: int, pid: int}> $templateRecords The template records to sort.
* @param array<int, int> $pageRootlinePositions A map of page IDs to their rootline positions.
*/
protected function sortTemplateRecordsByPageRootlinePosition(array &$templateRecords, array $pageRootlinePositions): void
{
usort($templateRecords, static fn(array $a, array $b): int => $pageRootlinePositions[$b['pid']] <=> $pageRootlinePositions[$a['pid']]);
}
}
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
"sys_template",
,"uid","pid","root","sorting","config"
,777,33,1,100,"page = PAGE"
,778,44,1,200,"page = PAGE"
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

use ApacheSolrForTypo3\Solr\System\Records\SystemTemplate\SystemTemplateRepository;
use ApacheSolrForTypo3\Solr\Tests\Integration\IntegrationTestBase;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Test;
use TYPO3\CMS\Core\Utility\GeneralUtility;

Expand All @@ -25,20 +26,61 @@
*/
class SystemTemplateRepositoryTest extends IntegrationTestBase
{
public static function rootLineDataProvider(): array
{
return [
'Rootline with template on page 33 (2nd)' => [
[
['uid' => 4], // No template
['uid' => 3], // No template
['uid' => 2], // No template
['uid' => 33], // Template here
['uid' => 1], // Current page
],
33,
],
'Rootline with template on page 44 (2nd)' => [
[
['uid' => 5], // No template
['uid' => 33], // Template here, but 44 is closer
['uid' => 2], // No template
['uid' => 44], // Template here
['uid' => 1], // Current page
],
44,
],
'Rootline with template on page 33 (3rd), page 44 (5th)' => [
[
['uid' => 44], // Template here, but 33 is closer
['uid' => 30], // No template
['uid' => 33], // Template here
['uid' => 20], // No template
['uid' => 10], // Current page
],
33,
],
'Rootline with template on page 44 (3rd), page 33 (5th)' => [
[
['uid' => 33], // Template here, but 44 is closer
['uid' => 30], // No template
['uid' => 44], // Template here
['uid' => 20], // No template
['uid' => 10], // Current page
],
44,
],
];
}

#[DataProvider('rootLineDataProvider')]
#[Test]
public function canFindOneClosestPageIdWithActiveTemplateByRootLine(): void
public function canFindOneClosestPageIdWithActiveTemplateByRootLine(array $fakeRootLine, int $expectedPageId): void
{
$this->importCSVDataSet(__DIR__ . '/Fixtures/sys_template.csv');

$fakeRootLine = [
['uid' => 100],
['uid' => 33],
['uid' => 8657],
];

/** @var SystemTemplateRepository $repository */
$repository = GeneralUtility::makeInstance(SystemTemplateRepository::class);
$closestPageIdWithActiveTemplate = $repository->findOneClosestPageIdWithActiveTemplateByRootLine($fakeRootLine);
self::assertEquals(33, $closestPageIdWithActiveTemplate, 'Can not find closest page id with active template.');
self::assertEquals($expectedPageId, $closestPageIdWithActiveTemplate, 'Can not find closest page id with active template.');
}
}
Loading