Skip to content

Commit afb986e

Browse files
committed
[TASK] Always delegate simulated TSFE via PSR-14 events instead of Site/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
1 parent a528113 commit afb986e

7 files changed

+106
-37
lines changed

Classes/Event/Indexing/AfterPageDocumentIsCreatedForIndexingEvent.php

+9-4
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use ApacheSolrForTypo3\Solr\System\Solr\Document\Document;
2323
use TYPO3\CMS\Core\Site\Entity\Site;
2424
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
25+
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
2526

2627
/**
2728
* Allows third party extensions to replace or modify the page document
@@ -36,9 +37,8 @@ final class AfterPageDocumentIsCreatedForIndexingEvent
3637
public function __construct(
3738
private Document $document,
3839
private readonly Item $indexQueueItem,
39-
private readonly Site $site,
40-
private readonly SiteLanguage $siteLanguage,
4140
private readonly array $record,
41+
private readonly TypoScriptFrontendController $tsfe,
4242
private readonly TypoScriptConfiguration $configuration
4343
) {}
4444

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

6565
public function getSite(): Site
6666
{
67-
return $this->site;
67+
return $this->tsfe->getSite();
6868
}
6969

7070
public function getSiteLanguage(): SiteLanguage
7171
{
72-
return $this->siteLanguage;
72+
return $this->tsfe->getLanguage();
7373
}
7474

7575
public function getRecord(): array
@@ -81,4 +81,9 @@ public function getConfiguration(): TypoScriptConfiguration
8181
{
8282
return $this->configuration;
8383
}
84+
85+
public function getTsfe(): TypoScriptFrontendController
86+
{
87+
return clone $this->tsfe;
88+
}
8489
}

Classes/Event/Indexing/BeforeDocumentIsProcessedForIndexingEvent.php

+10-5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use ApacheSolrForTypo3\Solr\System\Solr\Document\Document;
2222
use TYPO3\CMS\Core\Site\Entity\Site;
2323
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
24+
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
2425

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

3940
public function __construct(
4041
private readonly Document $document,
41-
private readonly Site $site,
42-
private readonly SiteLanguage $siteLanguage,
43-
private readonly Item $indexQueueItem
42+
private readonly Item $indexQueueItem,
43+
private readonly TypoScriptFrontendController $tsfe,
4444
) {
4545
$this->documents[] = $this->document;
4646
}
4747

4848
public function getSite(): Site
4949
{
50-
return $this->site;
50+
return $this->tsfe->getSite();
5151
}
5252

5353
public function getSiteLanguage(): SiteLanguage
5454
{
55-
return $this->siteLanguage;
55+
return $this->tsfe->getLanguage();
5656
}
5757

5858
public function getIndexQueueItem(): Item
@@ -80,4 +80,9 @@ public function getDocuments(): array
8080
{
8181
return $this->documents;
8282
}
83+
84+
public function getTsfe(): TypoScriptFrontendController
85+
{
86+
return clone $this->tsfe;
87+
}
8388
}

Classes/Event/Indexing/BeforeDocumentsAreIndexedEvent.php

+9-4
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use ApacheSolrForTypo3\Solr\System\Solr\Document\Document;
2222
use TYPO3\CMS\Core\Site\Entity\Site;
2323
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
24+
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
2425

2526
/**
2627
* An event to manipulate documents right before they get added to the Solr index.
@@ -32,21 +33,20 @@ class BeforeDocumentsAreIndexedEvent
3233
{
3334
public function __construct(
3435
private readonly Document $document,
35-
private readonly Site $site,
36-
private readonly SiteLanguage $siteLanguage,
3736
private readonly Item $indexQueueItem,
3837
/** @var Document[] */
3938
private array $documents,
39+
private readonly TypoScriptFrontendController $tsfe,
4040
) {}
4141

4242
public function getSite(): Site
4343
{
44-
return $this->site;
44+
return $this->tsfe->getSite();
4545
}
4646

4747
public function getSiteLanguage(): SiteLanguage
4848
{
49-
return $this->siteLanguage;
49+
return $this->tsfe->getLanguage();
5050
}
5151

5252
public function getIndexQueueItem(): Item
@@ -74,4 +74,9 @@ public function getDocuments(): array
7474
{
7575
return $this->documents;
7676
}
77+
78+
public function getTsfe(): TypoScriptFrontendController
79+
{
80+
return clone $this->tsfe;
81+
}
7782
}

Classes/Event/Indexing/BeforePageDocumentIsProcessedForIndexingEvent.php

+10-5
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
use ApacheSolrForTypo3\Solr\System\Solr\Document\Document;
2222
use TYPO3\CMS\Core\Site\Entity\Site;
2323
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
24+
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
2425

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

3839
public function __construct(
3940
private readonly Document $document,
40-
private readonly Site $site,
41-
private readonly SiteLanguage $siteLanguage,
42-
private readonly Item $indexQueueItem
41+
private readonly Item $indexQueueItem,
42+
private readonly TypoScriptFrontendController $tsfe,
4343
) {
4444
$this->documents[] = $this->document;
4545
}
4646

4747
public function getSite(): Site
4848
{
49-
return $this->site;
49+
return $this->tsfe->getSite();
5050
}
5151

5252
public function getSiteLanguage(): SiteLanguage
5353
{
54-
return $this->siteLanguage;
54+
return $this->tsfe->getLanguage();
5555
}
5656

5757
public function getIndexQueueItem(): Item
@@ -79,4 +79,9 @@ public function getDocuments(): array
7979
{
8080
return $this->documents;
8181
}
82+
83+
public function getTsfe(): TypoScriptFrontendController
84+
{
85+
return clone $this->tsfe;
86+
}
8287
}

Classes/IndexQueue/FrontendHelper/PageIndexer.php

+16-10
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
use Psr\Log\LogLevel;
3838
use Throwable;
3939
use TYPO3\CMS\Core\SingletonInterface;
40-
use TYPO3\CMS\Core\Site\Entity\Site;
4140
use TYPO3\CMS\Core\Site\Entity\SiteLanguage;
4241
use TYPO3\CMS\Core\Utility\GeneralUtility;
4342
use TYPO3\CMS\Core\Utility\MathUtility;
@@ -196,9 +195,9 @@ public function index(Item $indexQueueItem, TypoScriptFrontendController $tsfe):
196195
$this->solrConnection = $this->getSolrConnection($indexQueueItem, $tsfe->getLanguage(), $this->configuration->getLoggingExceptions());
197196

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

201-
$this->responseData['pageIndexed'] = (int)$this->indexPage($document, $indexQueueItem, $tsfe->getSite(), $tsfe->getLanguage());
200+
$this->responseData['pageIndexed'] = (int)$this->indexPage($document, $indexQueueItem, $tsfe);
202201
$this->responseData['originalPageDocument'] = (array)$document;
203202
$this->responseData['solrConnection'] = [
204203
'rootPage' => $indexQueueItem->getRootPageUid(),
@@ -261,9 +260,13 @@ protected function getIndexQueueItem(): ?Item
261260
* @param Document $pageDocument The page document created by this indexer.
262261
* @return Document An Apache Solr document representing the currently indexed page
263262
*/
264-
protected function substitutePageDocument(Document $pageDocument, Site $site, SiteLanguage $siteLanguage, array $pageRecord, Item $indexQueueItem): Document
265-
{
266-
$event = new AfterPageDocumentIsCreatedForIndexingEvent($pageDocument, $indexQueueItem, $site, $siteLanguage, $pageRecord, $this->configuration);
263+
protected function substitutePageDocument(
264+
Document $pageDocument,
265+
array $pageRecord,
266+
Item $indexQueueItem,
267+
TypoScriptFrontendController $tsfe,
268+
): Document {
269+
$event = new AfterPageDocumentIsCreatedForIndexingEvent($pageDocument, $indexQueueItem, $pageRecord, $tsfe, $this->configuration);
267270
$event = $this->getEventDispatcher()->dispatch($event);
268271
return $event->getDocument();
269272
}
@@ -284,15 +287,18 @@ protected function getPageDocument(TypoScriptFrontendController $tsfe, string $u
284287
*
285288
* @return bool TRUE after successfully indexing the page, FALSE on error
286289
*/
287-
public function indexPage(Document $pageDocument, Item $indexQueueItem, Site $site, SiteLanguage $siteLanguage): bool
288-
{
289-
$event = new BeforePageDocumentIsProcessedForIndexingEvent($pageDocument, $site, $siteLanguage, $indexQueueItem);
290+
public function indexPage(
291+
Document $pageDocument,
292+
Item $indexQueueItem,
293+
TypoScriptFrontendController $tsfe,
294+
): bool {
295+
$event = new BeforePageDocumentIsProcessedForIndexingEvent($pageDocument, $indexQueueItem, $tsfe);
290296
$event = $this->getEventDispatcher()->dispatch($event);
291297
$documents = $event->getDocuments();
292298

293299
$this->processDocuments($documents);
294300

295-
$event = new BeforeDocumentsAreIndexedEvent($pageDocument, $site, $siteLanguage, $indexQueueItem, $documents);
301+
$event = new BeforeDocumentsAreIndexedEvent($pageDocument, $indexQueueItem, $documents, $tsfe);
296302
$event = $this->getEventDispatcher()->dispatch($event);
297303
$documents = $event->getDocuments();
298304

Classes/IndexQueue/Indexer.php

+30-7
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
use TYPO3\CMS\Core\Site\SiteFinder;
4646
use TYPO3\CMS\Core\Utility\GeneralUtility;
4747
use TYPO3\CMS\Core\Utility\RootlineUtility;
48+
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
4849

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

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

172-
$event = new BeforeDocumentsAreIndexedEvent($itemDocument, $item->getSite()->getTypo3SiteObject(), $item->getSite()->getTypo3SiteObject()->getLanguageById($language), $item, $documents);
173+
$event = new BeforeDocumentsAreIndexedEvent(
174+
$itemDocument,
175+
$item,
176+
$documents,
177+
$this->getTsfeByItemAndLanguageId(
178+
$item,
179+
$language,
180+
),
181+
);
173182
$event = $this->eventDispatcher->dispatch($event);
174183
$documents = $event->getDocuments();
175184

@@ -309,7 +318,7 @@ protected function getFieldConfigurationFromItemRecordPage(Item $item, int $lang
309318
}
310319
}
311320

312-
protected function getPageIdOfItem(Item $item): int
321+
protected function getPageIdOfItem(Item $item): ?int
313322
{
314323
if ($item->getType() === 'pages') {
315324
return $item->getRecordUid();
@@ -368,14 +377,26 @@ protected function itemToDocument(Item $item, int $language = 0): ?Document
368377
if (!is_null($itemRecord)) {
369378
$itemIndexingConfiguration = $this->getItemTypeConfiguration($item, $language);
370379
$document = $this->getBaseDocument($item, $itemRecord);
371-
$pidToUse = $this->getPageIdOfItem($item);
372-
$tsfe = GeneralUtility::makeInstance(Tsfe::class)->getTsfeByPageIdAndLanguageId($pidToUse, $language, $item->getRootPageUid());
380+
$tsfe = $this->getTsfeByItemAndLanguageId($item, $language);
373381
$document = $this->addDocumentFieldsFromTyposcript($document, $itemIndexingConfiguration, $itemRecord, $tsfe);
374382
}
375383

376384
return $document;
377385
}
378386

387+
protected function getTsfeByItemAndLanguageId(
388+
Item $item,
389+
int $language = 0,
390+
): TypoScriptFrontendController {
391+
$pidToUse = $this->getPageIdOfItem($item);
392+
return GeneralUtility::makeInstance(Tsfe::class)
393+
->getTsfeByPageIdAndLanguageId(
394+
$pidToUse,
395+
$language,
396+
$item->getRootPageUid()
397+
);
398+
}
399+
379400
/**
380401
* Creates a Solr document with the basic / core fields set already.
381402
*
@@ -430,9 +451,11 @@ protected function getAdditionalDocuments(Document $itemDocument, Item $item, in
430451
{
431452
$event = new BeforeDocumentIsProcessedForIndexingEvent(
432453
$itemDocument,
433-
$item->getSite()->getTypo3SiteObject(),
434-
$item->getSite()->getTypo3SiteObject()->getLanguageById($language),
435-
$item
454+
$item,
455+
$this->getTsfeByItemAndLanguageId(
456+
$item,
457+
$language,
458+
)
436459
);
437460
$event = $this->eventDispatcher->dispatch($event);
438461
return $event->getDocuments();

Tests/Unit/IndexQueue/IndexerTest.php

+22-2
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
use ReflectionClass;
3737
use TYPO3\CMS\Core\Tests\Unit\Fixtures\EventDispatcher\MockEventDispatcher;
3838
use TYPO3\CMS\Core\Utility\GeneralUtility;
39+
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
3940

4041
/**
4142
* Class IndexerTest
@@ -63,7 +64,11 @@ public function canTriggerIndexingAndIndicateIndexStatus(int $httpStatus, bool $
6364

6465
$indexer = $this->getAccessibleMock(
6566
Indexer::class,
66-
['itemToDocument', 'processDocuments'],
67+
[
68+
'itemToDocument',
69+
'processDocuments',
70+
'getTsfeByItemAndLanguageId',
71+
],
6772
[],
6873
'',
6974
false
@@ -94,6 +99,12 @@ public function canTriggerIndexingAndIndicateIndexStatus(int $httpStatus, bool $
9499
->method('processDocuments')
95100
->with($itemMock, [$itemDocumentMock])
96101
->willReturnArgument(1);
102+
$indexer
103+
->expects(self::any())
104+
->method('getTsfeByItemAndLanguageId')
105+
->willReturn(
106+
$this->createMock(TypoScriptFrontendController::class)
107+
);
97108

98109
$writeServiceMock
99110
->expects(self::atLeastOnce())
@@ -138,12 +149,21 @@ public function canGetAdditionalDocuments(\Closure|null $listener, ?string $expe
138149
{
139150
$indexer = $this->getAccessibleMock(
140151
Indexer::class,
141-
null,
152+
[
153+
'getTsfeByItemAndLanguageId',
154+
],
142155
[],
143156
'',
144157
false
145158
);
146159

160+
$indexer
161+
->expects(self::any())
162+
->method('getTsfeByItemAndLanguageId')
163+
->willReturn(
164+
$this->createMock(TypoScriptFrontendController::class)
165+
);
166+
147167
$eventDispatcher = new MockEventDispatcher();
148168
if ($listener) {
149169
$eventDispatcher->addListener($listener);

0 commit comments

Comments
 (0)