Skip to content

Commit

Permalink
[TASK] Always delegate simulated TSFE via PSR-14 events instead of Si…
Browse files Browse the repository at this point in the history
…te/SiteLanguage

Almost all in EXT:solr 12-ALPHA introduced events propagate the Site and SiteLanguage objects, which are fetched from simulated TSFE object. That does not allow to use the required TSFE in subsequent processing directly, without instantiate TSFE objects manually.
EXT:solr* stack requires exact the same TSFE object, which is used by indexed Records/Pages, to process correctly.

This change makes it possible to reuse simulated TSFE object in listeners to be able to delegate right Core-Context objects for TYPO3 CORE components. 
The Site and SiteLanguage getters are still available.

Fixes: #3800
  • Loading branch information
dkd-kaehm committed Sep 22, 2023
1 parent a528113 commit afb986e
Show file tree
Hide file tree
Showing 7 changed files with 106 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use ApacheSolrForTypo3\Solr\System\Solr\Document\Document;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;

/**
* Allows third party extensions to replace or modify the page document
Expand All @@ -36,9 +37,8 @@ final class AfterPageDocumentIsCreatedForIndexingEvent
public function __construct(
private Document $document,
private readonly Item $indexQueueItem,
private readonly Site $site,
private readonly SiteLanguage $siteLanguage,
private readonly array $record,
private readonly TypoScriptFrontendController $tsfe,
private readonly TypoScriptConfiguration $configuration
) {}

Expand All @@ -64,12 +64,12 @@ public function getIndexingConfigurationName(): string

public function getSite(): Site
{
return $this->site;
return $this->tsfe->getSite();
}

public function getSiteLanguage(): SiteLanguage
{
return $this->siteLanguage;
return $this->tsfe->getLanguage();
}

public function getRecord(): array
Expand All @@ -81,4 +81,9 @@ public function getConfiguration(): TypoScriptConfiguration
{
return $this->configuration;
}

public function getTsfe(): TypoScriptFrontendController
{
return clone $this->tsfe;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use ApacheSolrForTypo3\Solr\System\Solr\Document\Document;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;

/**
* Allows third party extensions to provide additional documents which
Expand All @@ -38,21 +39,20 @@ class BeforeDocumentIsProcessedForIndexingEvent

public function __construct(
private readonly Document $document,
private readonly Site $site,
private readonly SiteLanguage $siteLanguage,
private readonly Item $indexQueueItem
private readonly Item $indexQueueItem,
private readonly TypoScriptFrontendController $tsfe,
) {
$this->documents[] = $this->document;
}

public function getSite(): Site
{
return $this->site;
return $this->tsfe->getSite();
}

public function getSiteLanguage(): SiteLanguage
{
return $this->siteLanguage;
return $this->tsfe->getLanguage();
}

public function getIndexQueueItem(): Item
Expand Down Expand Up @@ -80,4 +80,9 @@ public function getDocuments(): array
{
return $this->documents;
}

public function getTsfe(): TypoScriptFrontendController
{
return clone $this->tsfe;
}
}
13 changes: 9 additions & 4 deletions Classes/Event/Indexing/BeforeDocumentsAreIndexedEvent.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use ApacheSolrForTypo3\Solr\System\Solr\Document\Document;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;

/**
* An event to manipulate documents right before they get added to the Solr index.
Expand All @@ -32,21 +33,20 @@ class BeforeDocumentsAreIndexedEvent
{
public function __construct(
private readonly Document $document,
private readonly Site $site,
private readonly SiteLanguage $siteLanguage,
private readonly Item $indexQueueItem,
/** @var Document[] */
private array $documents,
private readonly TypoScriptFrontendController $tsfe,
) {}

public function getSite(): Site
{
return $this->site;
return $this->tsfe->getSite();
}

public function getSiteLanguage(): SiteLanguage
{
return $this->siteLanguage;
return $this->tsfe->getLanguage();
}

public function getIndexQueueItem(): Item
Expand Down Expand Up @@ -74,4 +74,9 @@ public function getDocuments(): array
{
return $this->documents;
}

public function getTsfe(): TypoScriptFrontendController
{
return clone $this->tsfe;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
use ApacheSolrForTypo3\Solr\System\Solr\Document\Document;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;

/**
* Allows to add more documents to the Solr index.
Expand All @@ -37,21 +38,20 @@ class BeforePageDocumentIsProcessedForIndexingEvent

public function __construct(
private readonly Document $document,
private readonly Site $site,
private readonly SiteLanguage $siteLanguage,
private readonly Item $indexQueueItem
private readonly Item $indexQueueItem,
private readonly TypoScriptFrontendController $tsfe,
) {
$this->documents[] = $this->document;
}

public function getSite(): Site
{
return $this->site;
return $this->tsfe->getSite();
}

public function getSiteLanguage(): SiteLanguage
{
return $this->siteLanguage;
return $this->tsfe->getLanguage();
}

public function getIndexQueueItem(): Item
Expand Down Expand Up @@ -79,4 +79,9 @@ public function getDocuments(): array
{
return $this->documents;
}

public function getTsfe(): TypoScriptFrontendController
{
return clone $this->tsfe;
}
}
26 changes: 16 additions & 10 deletions Classes/IndexQueue/FrontendHelper/PageIndexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
use Psr\Log\LogLevel;
use Throwable;
use TYPO3\CMS\Core\SingletonInterface;
use TYPO3\CMS\Core\Site\Entity\Site;
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\MathUtility;
Expand Down Expand Up @@ -196,9 +195,9 @@ public function index(Item $indexQueueItem, TypoScriptFrontendController $tsfe):
$this->solrConnection = $this->getSolrConnection($indexQueueItem, $tsfe->getLanguage(), $this->configuration->getLoggingExceptions());

$document = $this->getPageDocument($tsfe, $this->generatePageUrl($tsfe), $this->getAccessRootline(), $tsfe->MP);
$document = $this->substitutePageDocument($document, $tsfe->getSite(), $tsfe->getLanguage(), $tsfe->page, $indexQueueItem);
$document = $this->substitutePageDocument($document, $tsfe->page, $indexQueueItem, $tsfe);

$this->responseData['pageIndexed'] = (int)$this->indexPage($document, $indexQueueItem, $tsfe->getSite(), $tsfe->getLanguage());
$this->responseData['pageIndexed'] = (int)$this->indexPage($document, $indexQueueItem, $tsfe);
$this->responseData['originalPageDocument'] = (array)$document;
$this->responseData['solrConnection'] = [
'rootPage' => $indexQueueItem->getRootPageUid(),
Expand Down Expand Up @@ -261,9 +260,13 @@ protected function getIndexQueueItem(): ?Item
* @param Document $pageDocument The page document created by this indexer.
* @return Document An Apache Solr document representing the currently indexed page
*/
protected function substitutePageDocument(Document $pageDocument, Site $site, SiteLanguage $siteLanguage, array $pageRecord, Item $indexQueueItem): Document
{
$event = new AfterPageDocumentIsCreatedForIndexingEvent($pageDocument, $indexQueueItem, $site, $siteLanguage, $pageRecord, $this->configuration);
protected function substitutePageDocument(
Document $pageDocument,
array $pageRecord,
Item $indexQueueItem,
TypoScriptFrontendController $tsfe,
): Document {
$event = new AfterPageDocumentIsCreatedForIndexingEvent($pageDocument, $indexQueueItem, $pageRecord, $tsfe, $this->configuration);
$event = $this->getEventDispatcher()->dispatch($event);
return $event->getDocument();
}
Expand All @@ -284,15 +287,18 @@ protected function getPageDocument(TypoScriptFrontendController $tsfe, string $u
*
* @return bool TRUE after successfully indexing the page, FALSE on error
*/
public function indexPage(Document $pageDocument, Item $indexQueueItem, Site $site, SiteLanguage $siteLanguage): bool
{
$event = new BeforePageDocumentIsProcessedForIndexingEvent($pageDocument, $site, $siteLanguage, $indexQueueItem);
public function indexPage(
Document $pageDocument,
Item $indexQueueItem,
TypoScriptFrontendController $tsfe,
): bool {
$event = new BeforePageDocumentIsProcessedForIndexingEvent($pageDocument, $indexQueueItem, $tsfe);
$event = $this->getEventDispatcher()->dispatch($event);
$documents = $event->getDocuments();

$this->processDocuments($documents);

$event = new BeforeDocumentsAreIndexedEvent($pageDocument, $site, $siteLanguage, $indexQueueItem, $documents);
$event = new BeforeDocumentsAreIndexedEvent($pageDocument, $indexQueueItem, $documents, $tsfe);
$event = $this->getEventDispatcher()->dispatch($event);
$documents = $event->getDocuments();

Expand Down
37 changes: 30 additions & 7 deletions Classes/IndexQueue/Indexer.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@
use TYPO3\CMS\Core\Site\SiteFinder;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Core\Utility\RootlineUtility;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;

/**
* A general purpose indexer to be used for indexing of any kind of regular
Expand Down Expand Up @@ -169,7 +170,15 @@ protected function indexItem(Item $item, int $language = 0): bool

$documents = $this->processDocuments($item, $documents);

$event = new BeforeDocumentsAreIndexedEvent($itemDocument, $item->getSite()->getTypo3SiteObject(), $item->getSite()->getTypo3SiteObject()->getLanguageById($language), $item, $documents);
$event = new BeforeDocumentsAreIndexedEvent(
$itemDocument,
$item,
$documents,
$this->getTsfeByItemAndLanguageId(
$item,
$language,
),
);
$event = $this->eventDispatcher->dispatch($event);
$documents = $event->getDocuments();

Expand Down Expand Up @@ -309,7 +318,7 @@ protected function getFieldConfigurationFromItemRecordPage(Item $item, int $lang
}
}

protected function getPageIdOfItem(Item $item): int
protected function getPageIdOfItem(Item $item): ?int
{
if ($item->getType() === 'pages') {
return $item->getRecordUid();
Expand Down Expand Up @@ -368,14 +377,26 @@ protected function itemToDocument(Item $item, int $language = 0): ?Document
if (!is_null($itemRecord)) {
$itemIndexingConfiguration = $this->getItemTypeConfiguration($item, $language);
$document = $this->getBaseDocument($item, $itemRecord);
$pidToUse = $this->getPageIdOfItem($item);
$tsfe = GeneralUtility::makeInstance(Tsfe::class)->getTsfeByPageIdAndLanguageId($pidToUse, $language, $item->getRootPageUid());
$tsfe = $this->getTsfeByItemAndLanguageId($item, $language);
$document = $this->addDocumentFieldsFromTyposcript($document, $itemIndexingConfiguration, $itemRecord, $tsfe);
}

return $document;
}

protected function getTsfeByItemAndLanguageId(
Item $item,
int $language = 0,
): TypoScriptFrontendController {
$pidToUse = $this->getPageIdOfItem($item);
return GeneralUtility::makeInstance(Tsfe::class)
->getTsfeByPageIdAndLanguageId(
$pidToUse,
$language,
$item->getRootPageUid()
);
}

/**
* Creates a Solr document with the basic / core fields set already.
*
Expand Down Expand Up @@ -430,9 +451,11 @@ protected function getAdditionalDocuments(Document $itemDocument, Item $item, in
{
$event = new BeforeDocumentIsProcessedForIndexingEvent(
$itemDocument,
$item->getSite()->getTypo3SiteObject(),
$item->getSite()->getTypo3SiteObject()->getLanguageById($language),
$item
$item,
$this->getTsfeByItemAndLanguageId(
$item,
$language,
)
);
$event = $this->eventDispatcher->dispatch($event);
return $event->getDocuments();
Expand Down
24 changes: 22 additions & 2 deletions Tests/Unit/IndexQueue/IndexerTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
use ReflectionClass;
use TYPO3\CMS\Core\Tests\Unit\Fixtures\EventDispatcher\MockEventDispatcher;
use TYPO3\CMS\Core\Utility\GeneralUtility;
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;

/**
* Class IndexerTest
Expand Down Expand Up @@ -63,7 +64,11 @@ public function canTriggerIndexingAndIndicateIndexStatus(int $httpStatus, bool $

$indexer = $this->getAccessibleMock(
Indexer::class,
['itemToDocument', 'processDocuments'],
[
'itemToDocument',
'processDocuments',
'getTsfeByItemAndLanguageId',
],
[],
'',
false
Expand Down Expand Up @@ -94,6 +99,12 @@ public function canTriggerIndexingAndIndicateIndexStatus(int $httpStatus, bool $
->method('processDocuments')
->with($itemMock, [$itemDocumentMock])
->willReturnArgument(1);
$indexer
->expects(self::any())
->method('getTsfeByItemAndLanguageId')
->willReturn(
$this->createMock(TypoScriptFrontendController::class)
);

$writeServiceMock
->expects(self::atLeastOnce())
Expand Down Expand Up @@ -138,12 +149,21 @@ public function canGetAdditionalDocuments(\Closure|null $listener, ?string $expe
{
$indexer = $this->getAccessibleMock(
Indexer::class,
null,
[
'getTsfeByItemAndLanguageId',
],
[],
'',
false
);

$indexer
->expects(self::any())
->method('getTsfeByItemAndLanguageId')
->willReturn(
$this->createMock(TypoScriptFrontendController::class)
);

$eventDispatcher = new MockEventDispatcher();
if ($listener) {
$eventDispatcher->addListener($listener);
Expand Down

0 comments on commit afb986e

Please sign in to comment.