diff --git a/Classes/DataCollector/Utility/OverlayUtility.php b/Classes/DataCollector/Utility/OverlayUtility.php index 8aa125c5..5e2deedf 100644 --- a/Classes/DataCollector/Utility/OverlayUtility.php +++ b/Classes/DataCollector/Utility/OverlayUtility.php @@ -5,7 +5,6 @@ use PAGEmachine\Searchable\Utility\TsfeUtility; use TYPO3\CMS\Core\SingletonInterface; use TYPO3\CMS\Core\Utility\GeneralUtility; -use TYPO3\CMS\Core\Utility\VersionNumberUtility; use TYPO3\CMS\Frontend\Page\PageRepository; /* @@ -33,9 +32,7 @@ public static function getInstance() */ public function __construct(PageRepository $pageRepository = null) { - if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '10', '<')) { - TsfeUtility::createTSFE(); - } + TsfeUtility::createTSFE(); $this->pageRepository = $pageRepository ?: GeneralUtility::makeInstance(PageRepository::class); } diff --git a/Classes/LinkBuilder/PageLinkBuilder.php b/Classes/LinkBuilder/PageLinkBuilder.php index 6498f77f..1ee06208 100644 --- a/Classes/LinkBuilder/PageLinkBuilder.php +++ b/Classes/LinkBuilder/PageLinkBuilder.php @@ -27,7 +27,7 @@ class PageLinkBuilder extends AbstractLinkBuilder 'noCacheHash' => false, 'section' => '', 'linkAccessRestrictedPages' => false, - 'absolute' => false, + 'absolute' => true, 'addQueryString' => false, 'argumentsToBeExcludedFromQueryString' => [], 'addQueryStringMethod' => null, diff --git a/Classes/Middleware/UriBuilder.php b/Classes/Middleware/UriBuilder.php index 37f6e561..c2432301 100644 --- a/Classes/Middleware/UriBuilder.php +++ b/Classes/Middleware/UriBuilder.php @@ -9,6 +9,9 @@ use Psr\Http\Server\RequestHandlerInterface; use TYPO3\CMS\Core\Context\Context; use TYPO3\CMS\Core\Http\JsonResponse; +use TYPO3\CMS\Core\Routing\PageArguments; +use TYPO3\CMS\Core\Site\Entity\NullSite; +use TYPO3\CMS\Core\Site\SiteFinder; use TYPO3\CMS\Core\Utility\GeneralUtility; use TYPO3\CMS\Core\Utility\VersionNumberUtility; use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer; @@ -62,6 +65,16 @@ private function bootFrontendController(ServerRequestInterface $request): void return; } + $site = $request->getAttribute('site'); + + if ($site instanceof NullSite) { + $siteFinder = GeneralUtility::makeInstance(SiteFinder::class); + $site = array_values($siteFinder->getAllSites())[0] ?? $site; + $request = $request->withAttribute('site', $site); + $request = $request->withAttribute('language', $site->getDefaultLanguage()); + $request = $request->withAttribute('routing', new PageArguments($site->getRootPageId(), '0', [])); + } + $frontendController = GeneralUtility::makeInstance( TypoScriptFrontendController::class, GeneralUtility::makeInstance(Context::class), diff --git a/Classes/Utility/TsfeUtility.php b/Classes/Utility/TsfeUtility.php index eccb2f76..5b829f99 100644 --- a/Classes/Utility/TsfeUtility.php +++ b/Classes/Utility/TsfeUtility.php @@ -1,7 +1,13 @@ connectToDB(); + if (method_exists($GLOBALS['TSFE'], 'connectToDB')) { // TYPO3v9+ + // @extensionScannerIgnoreLine + $GLOBALS['TSFE']->connectToDB(); + } + + $GLOBALS['TSFE']->initFEuser(); + $GLOBALS['TSFE']->determineId(); + $GLOBALS['TSFE']->initTemplate(); + $GLOBALS['TSFE']->getConfigArray(); + $_SERVER['HTTP_HOST'] = 'localhost'; + GeneralUtility::flushInternalRuntimeCaches(); + $GLOBALS['TSFE']->preparePageContentGeneration(); } - $GLOBALS['TSFE']->initFEuser(); - $GLOBALS['TSFE']->determineId(); - $GLOBALS['TSFE']->initTemplate(); - $GLOBALS['TSFE']->getConfigArray(); - $_SERVER['HTTP_HOST'] = 'localhost'; - GeneralUtility::flushInternalRuntimeCaches(); - $GLOBALS['TSFE']->preparePageContentGeneration(); + return; } + + $siteFinder = GeneralUtility::makeInstance(SiteFinder::class); + $site = array_values($siteFinder->getAllSites())[0] ?? null; + + if ($site === null) { + throw new \RuntimeException('No site found for TSFE setup', 1610444900); + } + + $requestFactory = GeneralUtility::makeInstance(ServerRequestFactory::class); + $request = $requestFactory->createServerRequest('get', 'http://localhost') + ->withAttribute('site', $site) + ->withAttribute('language', $site->getDefaultLanguage()) + ->withAttribute('routing', new PageArguments($site->getRootPageId(), '0', [])) + ->withAttribute('frontend.user', GeneralUtility::makeInstance(FrontendUserAuthentication::class)); + $GLOBALS['TYPO3_REQUEST'] = $request; + + $frontendController = GeneralUtility::makeInstance( + TypoScriptFrontendController::class, + GeneralUtility::makeInstance(Context::class), + $request->getAttribute('site'), + $request->getAttribute('language'), + $request->getAttribute('routing'), + $request->getAttribute('frontend.user') + ); + $frontendController->fetch_the_id($request); + $frontendController->getConfigArray($request); + + $GLOBALS['TSFE'] = $frontendController; } } diff --git a/Tests/Functional/AbstractElasticsearchTest.php b/Tests/Functional/AbstractElasticsearchTest.php index def1f765..358b77e9 100644 --- a/Tests/Functional/AbstractElasticsearchTest.php +++ b/Tests/Functional/AbstractElasticsearchTest.php @@ -73,10 +73,10 @@ protected function setUp() ], ], 'indexers' => [ - 'pages' => [ + 'foo_pages' => [ 'className' => PagesIndexer::class, 'config' => [ - 'type' => 'test_pages', + 'type' => 'foo_pages', 'collector' => [ 'config' => [ 'pid' => 1, @@ -84,6 +84,28 @@ protected function setUp() ], ], ], + 'bar_pages' => [ + 'className' => PagesIndexer::class, + 'config' => [ + 'type' => 'bar_pages', + 'collector' => [ + 'config' => [ + 'pid' => 100, + ], + ], + ], + ], + 'qux_pages' => [ + 'className' => PagesIndexer::class, + 'config' => [ + 'type' => 'qux_pages', + 'collector' => [ + 'config' => [ + 'pid' => 200, + ], + ], + ], + ], 'content' => [ 'className' => TcaIndexer::class, 'config' => [ @@ -109,7 +131,17 @@ protected function setUp() $this->getDatabaseConnection()->insertArray('pages', [ 'uid' => 1, 'doktype' => PageRepository::DOKTYPE_DEFAULT, - 'title' => 'Root', + 'title' => 'Foo Root', + ]); + $this->getDatabaseConnection()->insertArray('pages', [ + 'uid' => 100, + 'doktype' => PageRepository::DOKTYPE_DEFAULT, + 'title' => 'Bar Root', + ]); + $this->getDatabaseConnection()->insertArray('pages', [ + 'uid' => 200, + 'doktype' => PageRepository::DOKTYPE_DEFAULT, + 'title' => 'Qux Root', ]); $typoScriptConstantsFile = 'EXT:searchable/Configuration/TypoScript/constants.typoscript'; @@ -122,6 +154,8 @@ protected function setUp() __DIR__ . '/Fixtures/TypoScript/page.typoscript', $typoScriptSetupFile, ]); + $this->setUpFrontendRootPage(100); + $this->setUpFrontendRootPage(200); $this->getDatabaseConnection()->updateArray( 'sys_template', [ diff --git a/Tests/Functional/Service/IndexingServiceTest.php b/Tests/Functional/Service/IndexingServiceTest.php index eaa95c49..2c915c6f 100644 --- a/Tests/Functional/Service/IndexingServiceTest.php +++ b/Tests/Functional/Service/IndexingServiceTest.php @@ -5,6 +5,8 @@ use PAGEmachine\Searchable\Service\IndexingService; use PAGEmachine\Searchable\Tests\Functional\AbstractElasticsearchTest; +use TYPO3\CMS\Core\Configuration\SiteConfiguration; +use TYPO3\CMS\Core\Core\Environment; use TYPO3\CMS\Core\Database\ConnectionPool; use TYPO3\CMS\Core\Log\LogLevel; use TYPO3\CMS\Core\Log\Writer\FileWriter; @@ -69,7 +71,7 @@ public function indexesRecordsFully(): void [ 'title' => 'Test page', 'searchable_meta' => [ - 'renderedLink' => version_compare(VersionNumberUtility::getCurrentTypo3Version(), '9', '>=') ? '/test-page/' : 'index.php?id=2', + 'renderedLink' => version_compare(VersionNumberUtility::getCurrentTypo3Version(), '9', '>=') ? '/test-page/' : 'http://localhost/index.php?id=2', ], ] ); @@ -124,7 +126,7 @@ public function indexesRecordTranslations(): void [ 'title' => 'Translated test page', 'searchable_meta' => [ - 'renderedLink' => version_compare(VersionNumberUtility::getCurrentTypo3Version(), '9', '>=') ? '/da/translated-test-page/' : 'index.php?id=2&L=1', + 'renderedLink' => version_compare(VersionNumberUtility::getCurrentTypo3Version(), '9', '>=') ? '/da/translated-test-page/' : 'http://localhost/index.php?id=2&L=1', ], ], 1 @@ -272,6 +274,66 @@ public function skipsPagesWithNoSearchFromIndexing(): void $this->assertDocumentInIndex(5); } + /** + * @test + */ + public function respectsSiteBase(): void + { + if (version_compare(VersionNumberUtility::getCurrentTypo3Version(), '9', '<')) { + $this->markTestSkipped('TYPO3v9+ only'); + } + + $siteConfiguration = GeneralUtility::makeInstance( + SiteConfiguration::class, + Environment::getConfigPath() . '/sites' + ); + $configuration = $siteConfiguration->load('100'); + $configuration['base'] = 'https://bar.example.org/'; + $siteConfiguration->write('100', $configuration); + + $configuration = $siteConfiguration->load('200'); + $configuration['base'] = 'https://qux.example.org/'; + $siteConfiguration->write('200', $configuration); + + $this->getDatabaseConnection()->insertArray('pages', [ + 'uid' => 101, + 'pid' => 100, + 'doktype' => PageRepository::DOKTYPE_DEFAULT, + 'title' => 'Bar test page', + 'slug' => '/bar-test-page/', + ]); + $this->getDatabaseConnection()->insertArray('pages', [ + 'uid' => 201, + 'pid' => 200, + 'doktype' => PageRepository::DOKTYPE_DEFAULT, + 'title' => 'Qux test page', + 'slug' => '/qux-test-page/', + ]); + + $this->assertIndexEmpty(); + + $this->indexingService->indexFull(); + + $this->assertDocumentInIndex( + 101, + [ + 'title' => 'Bar test page', + 'searchable_meta' => [ + 'renderedLink' => 'https://bar.example.org/bar-test-page/', + ], + ] + ); + $this->assertDocumentInIndex( + 201, + [ + 'title' => 'Qux test page', + 'searchable_meta' => [ + 'renderedLink' => 'https://qux.example.org/qux-test-page/', + ], + ] + ); + } + /** * @return void */ diff --git a/phpstan.neon b/phpstan.neon index 5fd13416..82eca434 100644 --- a/phpstan.neon +++ b/phpstan.neon @@ -21,15 +21,23 @@ parameters: path: Classes/Middleware/UriBuilder.php - message: '#TYPO3\\CMS\\Core\\Context\\.+#' paths: + - Classes/Middleware/UriBuilder.php - Classes/Service/IndexingService.php + - Classes/Utility/TsfeUtility.php - Classes/ViewHelpers/SiteLanguageViewHelper.php - message: '#TYPO3\\CMS\\Core\\Database\\PostProcessQueryHookInterface#' paths: - ext_localconf.php - Classes/Hook/DatabaseConnectionHook.php - - message: '#TYPO3\\CMS\\Core\\Context\\Context#' - path: Classes/Middleware/UriBuilder.php - message: '#TYPO3\\CMS\\Core\\Http\\JsonResponse#' path: Classes/Middleware/UriBuilder.php + - message: '#TYPO3\\CMS\\Core\\Routing\\.+#' + paths: + - Classes/Middleware/UriBuilder.php + - Classes/Utility/TsfeUtility.php + - message: '#TYPO3\\CMS\\Core\\Site\\.+#' + paths: + - Classes/Middleware/UriBuilder.php + - Classes/Utility/TsfeUtility.php reportUnmatchedIgnoredErrors: false