Skip to content

Commit a5aefa8

Browse files
committed
[BUGFIX] Delegate and adjust TYPO3 core context within indexing stack
This change fixes the issues related to delegation of TYPO3 core context, which is mandatory on multiple TYPO3 API calls to ensure proper function on all TYPO3 language modes. Fixes: #4409 Replaces: #4427
1 parent 3379672 commit a5aefa8

File tree

2 files changed

+78
-15
lines changed

2 files changed

+78
-15
lines changed

Classes/FrontendEnvironment/Tsfe.php

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
use ApacheSolrForTypo3\Solr\System\Configuration\ConfigurationPageResolver;
2020
use Doctrine\DBAL\Exception as DBALException;
2121
use JsonException;
22+
use ReflectionClass;
2223
use Throwable;
2324
use TYPO3\CMS\Backend\Utility\BackendUtility;
2425
use TYPO3\CMS\Core\Context\Context;
@@ -162,6 +163,10 @@ protected function initializeTsfe(int $pageId, int $language = 0, ?int $rootPage
162163
$serverRequest = $serverRequest->withAttribute('frontend.user', $feUser);
163164
/** @var TypoScriptFrontendController $tsfe */
164165
$tsfe = GeneralUtility::makeInstance(TypoScriptFrontendController::class);
166+
$this->setCoreContextOnTsfeObjectAndDependencies(
167+
$tsfe,
168+
$context,
169+
);
165170
$tsfe->id = $pageId;
166171
$tsfe->newCObj($serverRequest);
167172

@@ -361,4 +366,17 @@ protected function isRequestedPageAPartOfRequestedSite(int $pageId, ?int $rootPa
361366
}
362367
return $rootPageId === $site->getRootPageId();
363368
}
369+
370+
protected function setCoreContextOnTsfeObjectAndDependencies(
371+
TypoScriptFrontendController $tsfe,
372+
Context $context,
373+
): void {
374+
$tsfeReflection = new ReflectionClass($tsfe);
375+
$tsfeReflectionContextProperty = $tsfeReflection->getProperty('context');
376+
$tsfeReflectionContextProperty->setValue($tsfe, $context);
377+
$tsfe->sys_page = GeneralUtility::makeInstance(
378+
PageRepository::class,
379+
$context,
380+
);
381+
}
364382
}

Classes/IndexQueue/Indexer.php

Lines changed: 60 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,8 @@
2424
use ApacheSolrForTypo3\Solr\Event\Indexing\BeforeDocumentIsProcessedForIndexingEvent;
2525
use ApacheSolrForTypo3\Solr\Event\Indexing\BeforeDocumentsAreIndexedEvent;
2626
use ApacheSolrForTypo3\Solr\Exception as EXTSolrException;
27+
use ApacheSolrForTypo3\Solr\Exception\InvalidArgumentException;
28+
use ApacheSolrForTypo3\Solr\Exception\InvalidConnectionException;
2729
use ApacheSolrForTypo3\Solr\FieldProcessor\Service;
2830
use ApacheSolrForTypo3\Solr\FrontendEnvironment;
2931
use ApacheSolrForTypo3\Solr\FrontendEnvironment\Exception\Exception as FrontendEnvironmentException;
@@ -40,12 +42,15 @@
4042
use Psr\Log\LogLevel;
4143
use RuntimeException;
4244
use Throwable;
45+
use TYPO3\CMS\Core\Context\Context;
4346
use TYPO3\CMS\Core\Context\LanguageAspectFactory;
47+
use TYPO3\CMS\Core\Context\VisibilityAspect;
4448
use TYPO3\CMS\Core\Domain\Repository\PageRepository;
4549
use TYPO3\CMS\Core\Exception\SiteNotFoundException;
4650
use TYPO3\CMS\Core\Site\SiteFinder;
4751
use TYPO3\CMS\Core\Utility\GeneralUtility;
4852
use TYPO3\CMS\Core\Utility\RootlineUtility;
53+
use TYPO3\CMS\Frontend\ContentObject\Exception\ContentRenderingException;
4954
use TYPO3\CMS\Frontend\Controller\TypoScriptFrontendController;
5055

5156
/**
@@ -109,6 +114,7 @@ public function __construct(
109114
* @throws NoSolrConnectionFoundException
110115
* @throws SiteNotFoundException
111116
* @throws IndexingException
117+
* @throws ContentRenderingException
112118
*/
113119
public function index(Item $item): bool
114120
{
@@ -128,7 +134,7 @@ public function index(Item $item): bool
128134
* indexed.
129135
* If there is no translation for a single language, this item counts
130136
* as TRUE since it's not an error which that should make the item
131-
* being reindexed during another index run.
137+
* being re-indexed during another index run.
132138
*/
133139
$indexed = false;
134140
}
@@ -150,6 +156,7 @@ public function index(Item $item): bool
150156
* @throws FrontendEnvironmentException
151157
* @throws IndexingException
152158
* @throws SiteNotFoundException
159+
* @throws ContentRenderingException
153160
*/
154161
protected function indexItem(Item $item, int $language = 0): bool
155162
{
@@ -202,13 +209,12 @@ protected function indexItem(Item $item, int $language = 0): bool
202209
* types.
203210
*
204211
* @param Item $item The item to be indexed
205-
* @param int $language Language Id (sys_language.uid)
212+
* @param int $language Language ID (sys_language.uid)
206213
*
207214
* @return array|null The full record with fields of data to be used for indexing or NULL to prevent an item from being indexed
208215
*
209216
* @throws DBALException
210-
* @throws FrontendEnvironmentException
211-
* @throws SiteNotFoundException
217+
* @throws InvalidArgumentException
212218
*/
213219
protected function getFullItemRecord(Item $item, int $language = 0): ?array
214220
{
@@ -225,8 +231,7 @@ protected function getFullItemRecord(Item $item, int $language = 0): ?array
225231
* Returns the overlaid item record.
226232
*
227233
* @throws DBALException
228-
* @throws FrontendEnvironmentException
229-
* @throws SiteNotFoundException
234+
* @throws InvalidArgumentException
230235
*/
231236
protected function getItemRecordOverlayed(Item $item, int $language): ?array
232237
{
@@ -258,12 +263,33 @@ protected function getItemRecordOverlayed(Item $item, int $language): ?array
258263
$typo3site = $item->getSite()->getTypo3SiteObject();
259264
$typo3siteLanguage = $typo3site->getLanguageById($language);
260265

266+
/** @var Context $coreContext */
267+
$coreContext = clone GeneralUtility::makeInstance(Context::class);
268+
// TYPO3 by default enables a preview mode if a backend user is logged in,
269+
// the VisibilityAspect is configured to show hidden elements.
270+
// Due to this setting hidden relations/translations might be indexed
271+
// when running the Solr indexer via the TYPO3 backend.
272+
// To avoid this, the VisibilityAspect is adapted for indexing.
273+
$coreContext->setAspect(
274+
'visibility',
275+
GeneralUtility::makeInstance(
276+
VisibilityAspect::class,
277+
false,
278+
false,
279+
),
280+
);
281+
$languageAspect = LanguageAspectFactory::createFromSiteLanguage($typo3siteLanguage);
282+
$coreContext->setAspect('language', $languageAspect);
261283
/** @var PageRepository $pageRepository */
262-
$pageRepository = GeneralUtility::makeInstance(PageRepository::class);
284+
$pageRepository = GeneralUtility::makeInstance(
285+
PageRepository::class,
286+
$coreContext,
287+
);
288+
263289
return $pageRepository->getLanguageOverlay(
264290
$item->getType(),
265291
$itemRecord,
266-
LanguageAspectFactory::createFromSiteLanguage($typo3siteLanguage),
292+
$languageAspect,
267293
);
268294
}
269295

@@ -291,6 +317,7 @@ protected function isAFreeContentModeItemRecord(Item $item): bool
291317
* @return array Configuration array from TypoScript
292318
*
293319
* @throws DBALException
320+
* @throws SiteNotFoundException
294321
*/
295322
protected function getItemTypeConfiguration(Item $item, int $language = 0): array
296323
{
@@ -332,7 +359,7 @@ protected function getPageIdOfItem(Item $item): ?int
332359
/**
333360
* The method returns the field configuration of the items root page id (uid of the related root page).
334361
*
335-
* @throws DBALException
362+
* @throws SiteNotFoundException
336363
*/
337364
protected function getFieldConfigurationFromItemRootPage(Item $item, int $language, string $indexConfigurationName): array
338365
{
@@ -344,6 +371,8 @@ protected function getFieldConfigurationFromItemRootPage(Item $item, int $langua
344371
/**
345372
* In case of additionalStoragePid config recordPageId can be outside siteroot.
346373
* In that case we should not read TS config of foreign siteroot.
374+
*
375+
* @throws DBALException
347376
*/
348377
protected function isRootPageIdPartOfRootLine(Item $item): bool
349378
{
@@ -364,19 +393,22 @@ protected function isRootPageIdPartOfRootLine(Item $item): bool
364393
* record's fields onto Solr document fields as configured in TypoScript.
365394
*
366395
* @param Item $item An index queue item
367-
* @param int $language Language Id
396+
* @param int $language Language ID
368397
*
369398
* @return Document|null The Solr document converted from the record
370399
*
371400
* @throws FrontendEnvironmentException
372401
* @throws SiteNotFoundException
373402
* @throws DBALException
403+
* @throws ContentRenderingException
404+
* @throws InvalidArgumentException
374405
*/
375406
protected function itemToDocument(Item $item, int $language = 0): ?Document
376407
{
377408
$document = null;
378409

379410
$itemRecord = $this->getFullItemRecord($item, $language);
411+
380412
if (!is_null($itemRecord)) {
381413
$itemIndexingConfiguration = $this->getItemTypeConfiguration($item, $language);
382414
$document = $this->getBaseDocument($item, $itemRecord);
@@ -393,6 +425,11 @@ protected function itemToDocument(Item $item, int $language = 0): ?Document
393425
return $document;
394426
}
395427

428+
/**
429+
* @throws SiteNotFoundException
430+
* @throws FrontendEnvironmentException
431+
* @throws DBALException
432+
*/
396433
protected function getTsfeByItemAndLanguageId(
397434
Item $item,
398435
int $language = 0,
@@ -455,6 +492,10 @@ protected function getAccessRootline(Item $item): string
455492
* and allows to add more documents before processing all of them.
456493
*
457494
* @return Document[]
495+
*
496+
* @throws DBALException
497+
* @throws FrontendEnvironmentException
498+
* @throws SiteNotFoundException
458499
*/
459500
protected function getAdditionalDocuments(Document $itemDocument, Item $item, int $language): array
460501
{
@@ -481,6 +522,7 @@ protected function getAdditionalDocuments(Document $itemDocument, Item $item, in
481522
*
482523
* @throws DBALException
483524
* @throws EXTSolrException
525+
* @throws SiteNotFoundException
484526
*/
485527
protected function processDocuments(Item $item, array $documents): array
486528
{
@@ -510,8 +552,11 @@ protected function processDocuments(Item $item, array $documents): array
510552
*
511553
* @return SolrConnection[] An array of connections, the array's keys are the sys_language_uid of the language of the connection
512554
*
513-
* @throws NoSolrConnectionFoundException
514555
* @throws DBALException
556+
* @throws InvalidArgumentException
557+
* @throws InvalidConnectionException
558+
* @throws NoSolrConnectionFoundException
559+
* @throws SiteNotFoundException
515560
*/
516561
protected function getSolrConnectionsByItem(Item $item): array
517562
{
@@ -634,11 +679,10 @@ protected function getDefaultLanguageUid(Item $item, array $rootPageRecord, arra
634679
/**
635680
* Checks for which languages connections have been configured for translation overlays and returns these connections.
636681
*
637-
* @param array $translationOverlays
638-
* @param int $rootPageId
639682
* @return SolrConnection[]
640683
*
641-
* @throws DBALException
684+
* @throws InvalidConnectionException
685+
* @throws SiteNotFoundException
642686
*/
643687
protected function getConnectionsForIndexableLanguages(array $translationOverlays, int $rootPageId): array
644688
{
@@ -667,7 +711,7 @@ protected function getConnectionsForIndexableLanguages(array $translationOverlay
667711
/**
668712
* Enables logging dependent on the configuration of the item's site
669713
*
670-
* @throws DBALException
714+
* @throws SiteNotFoundException
671715
*/
672716
protected function setLogging(Item $item): void
673717
{
@@ -718,6 +762,7 @@ protected function log(Item $item, array $itemDocuments, ResponseAdapter $respon
718762
* Checks the given language, if it is in "free" mode.
719763
*
720764
* @throws DBALException
765+
* @throws InvalidArgumentException
721766
*/
722767
protected function isLanguageInAFreeContentMode(Item $item, int $language): bool
723768
{

0 commit comments

Comments
 (0)