From 51e29d4a73bb089b6a70f58822501b8a77d47fae Mon Sep 17 00:00:00 2001 From: Markus Friedrich Date: Thu, 15 Dec 2022 14:09:24 +0100 Subject: [PATCH] [BUGFIX:BP:11.5] Fix frontend Solr connection initialization Solr plugins are initializing Solr connections for all available languages, this causes wrong language initializations in the PageRenderer, as all created TypoScriptFrontendController instances will overwrite the language setting. By allowing to fetch the Solr configuration by TYPO3 site and a specific language this issue is solved and the initialization overhead is reduced. Resolves: #3423 --- Classes/ConnectionManager.php | 39 ++++++++- Classes/Controller/AbstractBaseController.php | 8 +- Classes/Domain/Site/SiteHashService.php | 50 ++++++++++-- Classes/Domain/Site/SiteRepository.php | 36 +-------- Classes/System/Util/SiteUtility.php | 66 +++++++++++++++ Configuration/Services.yaml | 5 ++ .../ApacheSolrDocument/RepositoryTest.php | 17 +++- .../Domain/Search/Query/QueryBuilderTest.php | 24 +++--- .../Domain/Search/Query/SuggestQueryTest.php | 7 +- .../Search/ResultSet/SearchResultSetTest.php | 15 ++-- .../Unit/Domain/Site/SiteHashServiceTest.php | 37 ++++++--- Tests/Unit/Query/Modifier/ElevationTest.php | 2 + Tests/Unit/Query/Modifier/FacetingTest.php | 9 ++- Tests/Unit/Search/RelevanceComponentTest.php | 80 ++++++++++++++++--- Tests/Unit/Search/SortingComponentTest.php | 12 ++- 15 files changed, 316 insertions(+), 91 deletions(-) diff --git a/Classes/ConnectionManager.php b/Classes/ConnectionManager.php index 0575f045d8..96581aeb31 100644 --- a/Classes/ConnectionManager.php +++ b/Classes/ConnectionManager.php @@ -23,11 +23,13 @@ use ApacheSolrForTypo3\Solr\System\Records\SystemLanguage\SystemLanguageRepository; use ApacheSolrForTypo3\Solr\System\Solr\Node; use ApacheSolrForTypo3\Solr\System\Solr\SolrConnection; +use ApacheSolrForTypo3\Solr\System\Util\SiteUtility; use Doctrine\DBAL\Driver\Exception as DBALDriverException; use InvalidArgumentException; use function json_encode; use Throwable; use TYPO3\CMS\Core\SingletonInterface; +use TYPO3\CMS\Core\Site\Entity\Site as Typo3Site; use TYPO3\CMS\Core\Utility\GeneralUtility; /** @@ -127,6 +129,34 @@ public function getConnectionByPageId(int $pageId, int $language = 0, string $mo } } + /** + * Gets a Solr connection for a TYPO3 site and language + * + * @param Typo3Site $typo3Site + * @param int $languageUid + * @return SolrConnection A Solr connection. + * @throws NoSolrConnectionFoundException + */ + public function getConnectionByTypo3Site(Typo3Site $typo3Site, int $languageUid = 0): SolrConnection + { + $config = SiteUtility::getSolrConnectionConfiguration($typo3Site, $languageUid); + if ($config === null) { + throw $this->buildNoConnectionExceptionForPageAndLanguage( + $typo3Site->getRootPageId(), + $languageUid + ); + } + + try { + return $this->getConnectionFromConfiguration($config); + } catch (InvalidArgumentException $e) { + throw $this->buildNoConnectionExceptionForPageAndLanguage( + $typo3Site->getRootPageId(), + $languageUid + ); + } + } + /** * Gets a Solr connection for a root page ID. * @@ -189,11 +219,16 @@ public function getConnectionsBySite(Site $site): array * * @param array $connection Connection configuration * @return string Connection label - * @todo Remove, since not used, or take used. + * @deprecated since v11.5 and will be removed in v11.6, as unused since v11.0.0 */ protected function buildConnectionLabel(array $connection): string { - return $connection['rootPageTitle'] + trigger_error( + 'ConnectionManager->buildConnectionLabel is deprecated since v11.5 and will be removed in v11.6, as unsed since v11.0.0', + E_USER_DEPRECATED + ); + + return $connection['connectionKey'] . ' (pid: ' . $connection['rootPageUid'] . ', language: ' . $this->systemLanguageRepository->findOneLanguageTitleByLanguageId($connection['language']) . ') - Read node: ' diff --git a/Classes/Controller/AbstractBaseController.php b/Classes/Controller/AbstractBaseController.php index eafe3b8dc5..3c17c9f4f0 100644 --- a/Classes/Controller/AbstractBaseController.php +++ b/Classes/Controller/AbstractBaseController.php @@ -25,7 +25,6 @@ use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration; use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager; use ApacheSolrForTypo3\Solr\System\Service\ConfigurationService; -use ApacheSolrForTypo3\Solr\Util; use TYPO3\CMS\Core\Context\Exception\AspectNotFoundException; use TYPO3\CMS\Core\TypoScript\TypoScriptService; use TYPO3\CMS\Core\Utility\GeneralUtility; @@ -223,9 +222,12 @@ protected function initializeSettings() */ protected function initializeSearch() { - /** @var ConnectionManager $solrConnection */ try { - $solrConnection = $this->objectManager->get(ConnectionManager::class)->getConnectionByPageId($this->typoScriptFrontendController->id, Util::getLanguageUid(), $this->typoScriptFrontendController->MP); + $solrConnection = GeneralUtility::makeInstance(ConnectionManager::class)->getConnectionByTypo3Site( + $this->typoScriptFrontendController->getSite(), + $this->typoScriptFrontendController->getLanguage()->getLanguageId() + ); + $search = $this->objectManager->get(Search::class, $solrConnection); /** @noinspection PhpParamsInspection */ diff --git a/Classes/Domain/Site/SiteHashService.php b/Classes/Domain/Site/SiteHashService.php index 0da68d33bf..b97c5c1e2c 100644 --- a/Classes/Domain/Site/SiteHashService.php +++ b/Classes/Domain/Site/SiteHashService.php @@ -17,8 +17,11 @@ namespace ApacheSolrForTypo3\Solr\Domain\Site; +use ApacheSolrForTypo3\Solr\System\Util\SiteUtility; use Doctrine\DBAL\Driver\Exception as DBALDriverException; use Throwable; +use TYPO3\CMS\Core\Exception\SiteNotFoundException; +use TYPO3\CMS\Core\Site\SiteFinder; use TYPO3\CMS\Core\Utility\GeneralUtility; /** @@ -30,6 +33,16 @@ */ class SiteHashService { + /** + * SiteFinder + */ + protected SiteFinder $siteFinder; + + public function __construct(SiteFinder $siteFinder) + { + $this->siteFinder = $siteFinder; + } + /** * Resolves magic keywords in allowed sites configuration. * Supported keywords: @@ -49,7 +62,7 @@ public function getAllowedSitesForPageIdAndAllowedSitesConfiguration( ?string $allowedSitesConfiguration = '' ): string { if ($allowedSitesConfiguration === '__all') { - return $this->getDomainListOfAllSites(); + return $this->getDomainListOfAllSites(); } if ($allowedSitesConfiguration === '*') { return '*'; @@ -85,10 +98,13 @@ public function getSiteHashForDomain(string $domain): string */ protected function getDomainListOfAllSites(): string { - $sites = $this->getAvailableSites(); + $sites = $this->siteFinder->getAllSites(); $domains = []; - foreach ($sites as $site) { - $domains[] = $site->getDomain(); + foreach ($sites as $typo3Site) { + $connections = SiteUtility::getAllSolrConnectionConfigurations($typo3Site); + if (!empty($connections)) { + $domains[] = $typo3Site->getBase()->getHost(); + } } return implode(',', $domains); @@ -104,7 +120,13 @@ protected function getDomainListOfAllSites(): string */ protected function getDomainByPageIdAndReplaceMarkers(int $pageId, string $allowedSitesConfiguration): string { - $domainOfPage = $this->getSiteByPageId($pageId)->getDomain(); + try { + $typo3Site = $this->siteFinder->getSiteByPageId($pageId); + $domainOfPage = $typo3Site->getBase()->getHost(); + } catch (SiteNotFoundException $e) { + return ''; + } + $allowedSites = str_replace(['__solr_current_site', '__current_site'], $domainOfPage, $allowedSitesConfiguration); return (string)$allowedSites; } @@ -113,18 +135,30 @@ protected function getDomainByPageIdAndReplaceMarkers(int $pageId, string $allow * @return Site[] * @throws DBALDriverException * @throws Throwable + * @deprecated since v11.5 and will be removed in v11.6, SiteHashService no longer requires/uses Solr sites */ protected function getAvailableSites(): array { + trigger_error( + 'SiteHashService no longer requires/uses Solr sites ' . __METHOD__ . ' of class ' . __CLASS__ . ' is deprecated since v11.5 and will be removed in v11.6. Use SiteFinder instead or initizalize own objects', + E_USER_DEPRECATED + ); + return $this->getSiteRepository()->getAvailableSites(); } /** * @param int $pageId * @return SiteInterface + * @deprecated since v11.5 and will be removed in v11.6, SiteHashService no longer requires/uses Solr sites */ protected function getSiteByPageId(int $pageId): SiteInterface { + trigger_error( + 'SiteHashService no longer requires/uses Solr sites ' . __METHOD__ . ' of class ' . __CLASS__ . ' is deprecated since v11.5 and will be removed in v11.6. Use SiteFinder instead or initizalize own objects', + E_USER_DEPRECATED + ); + return $this->getSiteRepository()->getSiteByPageId($pageId); } @@ -132,9 +166,15 @@ protected function getSiteByPageId(int $pageId): SiteInterface * Get a reference to SiteRepository * * @return SiteRepository + * @deprecated since v11.5 and will be removed in v11.6, SiteHashService no longer requires/uses Solr sites */ protected function getSiteRepository(): SiteRepository { + trigger_error( + 'SiteHashService no longer requires/uses Solr sites ' . __METHOD__ . ' of class ' . __CLASS__ . ' is deprecated since v11.5 and will be removed in v11.6. Use SiteFinder instead or initizalize own objects', + E_USER_DEPRECATED + ); + return GeneralUtility::makeInstance(SiteRepository::class); } } diff --git a/Classes/Domain/Site/SiteRepository.php b/Classes/Domain/Site/SiteRepository.php index 1db973589d..7952cd999a 100644 --- a/Classes/Domain/Site/SiteRepository.php +++ b/Classes/Domain/Site/SiteRepository.php @@ -290,39 +290,9 @@ protected function buildTypo3ManagedSite(array $rootPageRecord): ?Site $solrConnectionConfigurations = []; foreach ($availableLanguageIds as $languageUid) { - $solrEnabled = SiteUtility::getConnectionProperty($typo3Site, 'enabled', $languageUid, 'read', true); - $solrReadCore = SiteUtility::getConnectionProperty($typo3Site, 'core', $languageUid, 'read'); - $solrWriteCore = SiteUtility::getConnectionProperty($typo3Site, 'core', $languageUid, 'write'); - if ($solrEnabled && !empty($solrReadCore) && !empty($solrWriteCore)) { - $solrConnectionConfigurations[$languageUid] = [ - 'connectionKey' => $rootPageRecord['uid'] . '|' . $languageUid, - 'rootPageTitle' => $rootPageRecord['title'], - 'rootPageUid' => $rootPageRecord['uid'], - 'read' => [ - 'scheme' => SiteUtility::getConnectionProperty($typo3Site, 'scheme', $languageUid, 'read', 'http'), - 'host' => SiteUtility::getConnectionProperty($typo3Site, 'host', $languageUid, 'read', 'localhost'), - 'port' => (int)SiteUtility::getConnectionProperty($typo3Site, 'port', $languageUid, 'read', 8983), - // @todo: transform core to path - 'path' => - SiteUtility::getConnectionProperty($typo3Site, 'path', $languageUid, 'read', '/solr/') . - $solrReadCore . '/' , - 'username' => SiteUtility::getConnectionProperty($typo3Site, 'username', $languageUid, 'read', ''), - 'password' => SiteUtility::getConnectionProperty($typo3Site, 'password', $languageUid, 'read', ''), - ], - 'write' => [ - 'scheme' => SiteUtility::getConnectionProperty($typo3Site, 'scheme', $languageUid, 'write', 'http'), - 'host' => SiteUtility::getConnectionProperty($typo3Site, 'host', $languageUid, 'write', 'localhost'), - 'port' => (int)SiteUtility::getConnectionProperty($typo3Site, 'port', $languageUid, 'write', 8983), - // @todo: transform core to path - 'path' => - SiteUtility::getConnectionProperty($typo3Site, 'path', $languageUid, 'write', '/solr/') . - $solrWriteCore . '/' , - 'username' => SiteUtility::getConnectionProperty($typo3Site, 'username', $languageUid, 'write', ''), - 'password' => SiteUtility::getConnectionProperty($typo3Site, 'password', $languageUid, 'write', ''), - ], - - 'language' => $languageUid, - ]; + $solrConnection = SiteUtility::getSolrConnectionConfiguration($typo3Site, $languageUid); + if ($solrConnection !== null) { + $solrConnectionConfigurations[$languageUid] = $solrConnection; } } diff --git a/Classes/System/Util/SiteUtility.php b/Classes/System/Util/SiteUtility.php index 72252920eb..aa1318a1d8 100644 --- a/Classes/System/Util/SiteUtility.php +++ b/Classes/System/Util/SiteUtility.php @@ -83,6 +83,72 @@ public static function getConnectionProperty( return $value; } + /** + * Builds the Solr connection configuration + * + * @param Site $typo3Site + * @param int $languageUid + * @return array|null + */ + public static function getSolrConnectionConfiguration(Site $typo3Site, int $languageUid): ?array + { + $solrEnabled = self::getConnectionProperty($typo3Site, 'enabled', $languageUid, 'read', true); + $solrReadCore = self::getConnectionProperty($typo3Site, 'core', $languageUid, 'read'); + $solrWriteCore = self::getConnectionProperty($typo3Site, 'core', $languageUid, 'write'); + if (!$solrEnabled || empty($solrReadCore) || empty($solrWriteCore)) { + return null; + } + + $rootPageUid = $typo3Site->getRootPageId(); + return [ + 'connectionKey' => $rootPageUid . '|' . $languageUid, + 'rootPageUid' => $rootPageUid, + 'read' => [ + 'scheme' => self::getConnectionProperty($typo3Site, 'scheme', $languageUid, 'read', 'http'), + 'host' => self::getConnectionProperty($typo3Site, 'host', $languageUid, 'read', 'localhost'), + 'port' => (int)self::getConnectionProperty($typo3Site, 'port', $languageUid, 'read', 8983), + // @todo: transform core to path + 'path' => + self::getConnectionProperty($typo3Site, 'path', $languageUid, 'read', '/solr/') . + $solrReadCore . '/' , + 'username' => self::getConnectionProperty($typo3Site, 'username', $languageUid, 'read', ''), + 'password' => self::getConnectionProperty($typo3Site, 'password', $languageUid, 'read', ''), + ], + 'write' => [ + 'scheme' => self::getConnectionProperty($typo3Site, 'scheme', $languageUid, 'write', 'http'), + 'host' => self::getConnectionProperty($typo3Site, 'host', $languageUid, 'write', 'localhost'), + 'port' => (int)self::getConnectionProperty($typo3Site, 'port', $languageUid, 'write', 8983), + // @todo: transform core to path + 'path' => + self::getConnectionProperty($typo3Site, 'path', $languageUid, 'write', '/solr/') . + $solrWriteCore . '/' , + 'username' => self::getConnectionProperty($typo3Site, 'username', $languageUid, 'write', ''), + 'password' => self::getConnectionProperty($typo3Site, 'password', $languageUid, 'write', ''), + ], + + 'language' => $languageUid, + ]; + } + + /** + * Builds the Solr connection configuration for all languages of given TYPO3 site + * + * @param Site $typo3Site + * @return array + */ + public static function getAllSolrConnectionConfigurations(Site $typo3Site): array + { + $connections = []; + foreach ($typo3Site->getLanguages() as $language) { + $connection = self::getSolrConnectionConfiguration($typo3Site, $language->getLanguageId()); + if ($connection !== null) { + $connections[$language->getLanguageId()] = $connection; + } + } + + return $connections; + } + /** * Resolves site configuration properties. * Language context properties have precedence over global settings. diff --git a/Configuration/Services.yaml b/Configuration/Services.yaml index b8910c445a..180c49352f 100644 --- a/Configuration/Services.yaml +++ b/Configuration/Services.yaml @@ -25,6 +25,11 @@ services: $frontendEnvironment: '@ApacheSolrForTypo3\Solr\FrontendEnvironment' $tcaService: '@ApacheSolrForTypo3\Solr\System\TCA\TCAService' $indexQueue: '@ApacheSolrForTypo3\Solr\IndexQueue\Queue' + + ApacheSolrForTypo3\Solr\Domain\Site\SiteHashService: + public: true + autowire: true + ApacheSolrForTypo3\Solr\EventListener\EnhancedRouting\CachedUrlModifier: tags: - name: event.listener diff --git a/Tests/Unit/Domain/Search/ApacheSolrDocument/RepositoryTest.php b/Tests/Unit/Domain/Search/ApacheSolrDocument/RepositoryTest.php index 3f245a2618..0006f57e8d 100644 --- a/Tests/Unit/Domain/Search/ApacheSolrDocument/RepositoryTest.php +++ b/Tests/Unit/Domain/Search/ApacheSolrDocument/RepositoryTest.php @@ -55,7 +55,14 @@ class RepositoryTest extends UnitTest public function findOneByPageIdAndByLanguageIdReturnsFirstFoundDocument() { $apacheSolrDocumentCollection = [new Document(), new Document()]; - $apacheSolrDocumentRepository = $this->getAccessibleMock(Repository::class, ['findByPageIdAndByLanguageId']); + $apacheSolrDocumentRepository = $this->getAccessibleMock( + Repository::class, + ['findByPageIdAndByLanguageId'], + [], + '', + false + ); + $apacheSolrDocumentRepository ->expects(self::exactly(1)) ->method('findByPageIdAndByLanguageId') @@ -93,7 +100,13 @@ public function findByPageIdAndByLanguageIdThrowsInvalidArgumentExceptionIfLangu public function findByPageIdAndByLanguageIdReturnsEmptyCollectionIfConnectionToSolrServerCanNotBeEstablished() { /* @var $apacheSolrDocumentRepository Repository */ - $apacheSolrDocumentRepository = $this->getAccessibleMock(Repository::class, ['initializeSearch']); + $apacheSolrDocumentRepository = $this->getAccessibleMock( + Repository::class, + ['initializeSearch'], + [], + '', + false + ); $apacheSolrDocumentRepository ->expects(self::exactly(1)) ->method('initializeSearch') diff --git a/Tests/Unit/Domain/Search/Query/QueryBuilderTest.php b/Tests/Unit/Domain/Search/Query/QueryBuilderTest.php index 1724c92340..5f0bc4cfd7 100644 --- a/Tests/Unit/Domain/Search/Query/QueryBuilderTest.php +++ b/Tests/Unit/Domain/Search/Query/QueryBuilderTest.php @@ -93,7 +93,7 @@ protected function getAllQueryParameters(Query $searchQuery) */ protected function getInitializedTestSearchQuery(string $queryString = '', TypoScriptConfiguration $fakeConfiguration = null): SearchQuery { - $builder = new QueryBuilder($fakeConfiguration, $this->loggerMock); + $builder = new QueryBuilder($fakeConfiguration, $this->loggerMock, $this->siteHashServiceMock); return $builder->buildSearchQuery($queryString); } @@ -379,7 +379,7 @@ public function noFiltersAreSetAfterInitialization() public function addsCorrectAccessFilterForAnonymousUser() { $query = $this->getInitializedTestSearchQuery(); - $queryBuilder = new QueryBuilder($this->configurationMock, $this->loggerMock); + $queryBuilder = new QueryBuilder($this->configurationMock, $this->loggerMock, $this->siteHashServiceMock); $queryBuilder->startFrom($query)->useUserAccessGroups([-1, 0]); $queryParameters = $this->getAllQueryParameters($query); self::assertSame('{!typo3access}-1,0', $queryParameters['fq'], 'Accessfilter was not applied'); @@ -391,7 +391,7 @@ public function addsCorrectAccessFilterForAnonymousUser() public function grantsAccessToGroupZeroIfNoGroupsProvided() { $query = $this->getInitializedTestSearchQuery(); - $queryBuilder = new QueryBuilder($this->configurationMock, $this->loggerMock); + $queryBuilder = new QueryBuilder($this->configurationMock, $this->loggerMock, $this->siteHashServiceMock); $queryBuilder->startFrom($query)->useUserAccessGroups([]); $queryParameters = $this->getAllQueryParameters($query); self::assertSame('{!typo3access}0', $queryParameters['fq'], 'Changed accessfilter was not applied'); @@ -403,7 +403,7 @@ public function grantsAccessToGroupZeroIfNoGroupsProvided() public function grantsAccessToGroupZeroIfZeroNotProvided() { $query = $this->getInitializedTestSearchQuery(); - $queryBuilder = new QueryBuilder($this->configurationMock, $this->loggerMock); + $queryBuilder = new QueryBuilder($this->configurationMock, $this->loggerMock, $this->siteHashServiceMock); $queryBuilder->startFrom($query)->useUserAccessGroups([5]); $queryParameters = $this->getAllQueryParameters($query); self::assertSame('{!typo3access}0,5', $queryParameters['fq'], 'Access filter was not applied as expected'); @@ -415,7 +415,7 @@ public function grantsAccessToGroupZeroIfZeroNotProvided() public function filtersDuplicateAccessGroups() { $query = $this->getInitializedTestSearchQuery(); - $queryBuilder = new QueryBuilder($this->configurationMock, $this->loggerMock); + $queryBuilder = new QueryBuilder($this->configurationMock, $this->loggerMock, $this->siteHashServiceMock); $queryBuilder->startFrom($query)->useUserAccessGroups([1, 1]); $queryParameters = $this->getAllQueryParameters($query); self::assertSame('{!typo3access}0,1', $queryParameters['fq'], 'Access filter was not applied as expected'); @@ -427,7 +427,7 @@ public function filtersDuplicateAccessGroups() public function allowsOnlyOneAccessFilter() { $query = $this->getInitializedTestSearchQuery(); - $queryBuilder = new QueryBuilder($this->configurationMock, $this->loggerMock); + $queryBuilder = new QueryBuilder($this->configurationMock, $this->loggerMock, $this->siteHashServiceMock); $queryBuilder->startFrom($query)->useUserAccessGroups([1])->useUserAccessGroups([2]); $queryParameters = $this->getAllQueryParameters($query); @@ -910,7 +910,7 @@ public function canTestNumberOfSuggestionsToTryFromConfiguration() */ public function canUseConfiguredVariantsFieldWhenVariantsAreActive() { - $fakeConfigurationArray['plugin.']['tx_solr.']['search.']['variants'] = 1; + $fakeConfigurationArray = ['plugin.' => ['tx_solr.' => ['search.' => ['variants' => 1]]]]; $fakeConfigurationArray['plugin.']['tx_solr.']['search.']['variants.'] = [ 'variantField' => 'myField', ]; @@ -926,7 +926,7 @@ public function canUseConfiguredVariantsFieldWhenVariantsAreActive() */ public function canUseConfiguredVariantsExpandAndRowCount() { - $fakeConfigurationArray['plugin.']['tx_solr.']['search.']['variants'] = 1; + $fakeConfigurationArray = ['plugin.' => ['tx_solr.' => ['search.' => ['variants' => 1]]]]; $fakeConfigurationArray['plugin.']['tx_solr.']['search.']['variants.'] = [ 'variantField' => 'variants', 'expand' => true, @@ -945,7 +945,7 @@ public function canUseConfiguredVariantsExpandAndRowCount() */ public function expandRowsIsNotSetWhenExpandIsInactive() { - $fakeConfigurationArray['plugin.']['tx_solr.']['search.']['variants'] = 1; + $fakeConfigurationArray = ['plugin.' => ['tx_solr.' => ['search.' => ['variants' => 1]]]]; $fakeConfigurationArray['plugin.']['tx_solr.']['search.']['variants.'] = [ 'variantField' => 'variants', 'expand' => false, @@ -1256,7 +1256,7 @@ public function canBuildExpectedQueryUrlFromCombinedQuery() $fieldCollapsing = new FieldCollapsing(true); - $queryBuilder = new QueryBuilder($this->configurationMock, $this->loggerMock); + $queryBuilder = new QueryBuilder($this->configurationMock, $this->loggerMock, $this->siteHashServiceMock); $query = $queryBuilder->newSearchQuery('hello world') ->useFilter('color:red') ->useUserAccessGroups([1, 2, 3]) @@ -1612,7 +1612,7 @@ public function canBuildSuggestQuery() 'numberOfSuggestions' => 10, ]); $this->builder = $this->getMockBuilder(QueryBuilder::class) - ->setConstructorArgs([$this->configurationMock, $this->loggerMock]) + ->setConstructorArgs([$this->configurationMock, $this->loggerMock, $this->siteHashServiceMock]) ->onlyMethods(['useSiteHashFromTypoScript']) ->getMock(); @@ -1634,7 +1634,7 @@ public function alternativeQueryIsWildCardQueryForSuggestQuery() 'numberOfSuggestions' => 10, ]); $this->builder = $this->getMockBuilder(QueryBuilder::class) - ->setConstructorArgs([$this->configurationMock, $this->loggerMock]) + ->setConstructorArgs([$this->configurationMock, $this->loggerMock, $this->siteHashServiceMock]) ->onlyMethods(['useSiteHashFromTypoScript']) ->getMock(); diff --git a/Tests/Unit/Domain/Search/Query/SuggestQueryTest.php b/Tests/Unit/Domain/Search/Query/SuggestQueryTest.php index 0a943dd4e4..7acfd6c1f0 100644 --- a/Tests/Unit/Domain/Search/Query/SuggestQueryTest.php +++ b/Tests/Unit/Domain/Search/Query/SuggestQueryTest.php @@ -17,6 +17,7 @@ use ApacheSolrForTypo3\Solr\Domain\Search\Query\QueryBuilder; use ApacheSolrForTypo3\Solr\Domain\Search\Query\SuggestQuery; +use ApacheSolrForTypo3\Solr\Domain\Site\SiteHashService; use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration; use ApacheSolrForTypo3\Solr\Tests\Unit\UnitTest; @@ -38,7 +39,7 @@ public function testSuggestQueryDoesNotUseFieldCollapsing() ]; $fakeConfiguration = new TypoScriptConfiguration($fakeConfigurationArray); - $queryBuilder = new QueryBuilder($fakeConfiguration); + $queryBuilder = new QueryBuilder($fakeConfiguration, null, $this->createMock(SiteHashService::class)); $suggestQuery = $queryBuilder->newSuggestQuery('type')->getQuery(); self::assertNull($suggestQuery->getFilterQuery('fieldCollapsing'), 'Collapsing should never be active for a suggest query, even when active'); @@ -52,7 +53,7 @@ public function testSuggestQueryUsesFilterList() $fakeConfiguration = new TypoScriptConfiguration([]); $suggestQuery = new SuggestQuery('typ', $fakeConfiguration); - $queryBuilder = new QueryBuilder($fakeConfiguration); + $queryBuilder = new QueryBuilder($fakeConfiguration, null, $this->createMock(SiteHashService::class)); $queryBuilder->startFrom($suggestQuery)->useFilter('+type:pages'); $queryParameters = $suggestQuery->getRequestBuilder()->build($suggestQuery)->getParams(); self::assertSame('+type:pages', $queryParameters['fq'], 'Filter was not added to the suggest query parameters'); @@ -66,7 +67,7 @@ public function testSuggestQueryDoesNotErrorOnEmptyKeywords() $fakeConfiguration = new TypoScriptConfiguration([]); $suggestQuery = new SuggestQuery(' ', $fakeConfiguration); - $queryBuilder = new QueryBuilder($fakeConfiguration); + $queryBuilder = new QueryBuilder($fakeConfiguration, null, $this->createMock(SiteHashService::class)); $queryBuilder->startFrom($suggestQuery)->useFilter('+type:pages'); $queryParameters = $suggestQuery->getRequestBuilder()->build($suggestQuery)->getParams(); self::assertSame('', $queryParameters['q'], 'Query is expected to be empty, but is not'); diff --git a/Tests/Unit/Domain/Search/ResultSet/SearchResultSetTest.php b/Tests/Unit/Domain/Search/ResultSet/SearchResultSetTest.php index d8fb6b41c8..53d48d5095 100644 --- a/Tests/Unit/Domain/Search/ResultSet/SearchResultSetTest.php +++ b/Tests/Unit/Domain/Search/ResultSet/SearchResultSetTest.php @@ -19,6 +19,7 @@ use ApacheSolrForTypo3\Solr\Domain\Search\Query\Helper\EscapeService; use ApacheSolrForTypo3\Solr\Domain\Search\Query\Query; +use ApacheSolrForTypo3\Solr\Domain\Search\Query\QueryBuilder; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Result\SearchResult; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\SearchResultSet; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\SearchResultSetService; @@ -62,11 +63,6 @@ class SearchResultSetTest extends UnitTest */ protected $queryMock; - /** - * @var SiteHashService - */ - protected $siteHashServiceMock; - /** * @var EscapeService */ @@ -83,10 +79,15 @@ protected function setUp(): void $this->searchMock = $this->getDumbMock(Search::class); $this->solrLogManagerMock = $this->getDumbMock(SolrLogManager::class); - $this->siteHashServiceMock = $this->getDumbMock(SiteHashService::class); $this->escapeServiceMock = $this->getDumbMock(EscapeService::class); $this->escapeServiceMock->expects(self::any())->method('escape')->willReturnArgument(0); + $queryBuilder = new QueryBuilder( + $this->configurationMock, + $this->solrLogManagerMock, + $this->createMock(SiteHashService::class) + ); + $this->objectManagerMock = $this->createMock(ObjectManager::class); $this->searchResultSetService = $this->getMockBuilder(SearchResultSetService::class) ->onlyMethods(['getRegisteredSearchComponents']) @@ -95,7 +96,7 @@ protected function setUp(): void $this->searchMock, $this->solrLogManagerMock, null, - null, + $queryBuilder, $this->objectManagerMock, ]) ->getMock(); diff --git a/Tests/Unit/Domain/Site/SiteHashServiceTest.php b/Tests/Unit/Domain/Site/SiteHashServiceTest.php index 215ddc6c3a..f003d4a853 100644 --- a/Tests/Unit/Domain/Site/SiteHashServiceTest.php +++ b/Tests/Unit/Domain/Site/SiteHashServiceTest.php @@ -15,9 +15,12 @@ namespace ApacheSolrForTypo3\Solr\Tests\Unit\Domain\Site; -use ApacheSolrForTypo3\Solr\Domain\Site\Site; use ApacheSolrForTypo3\Solr\Domain\Site\SiteHashService; use ApacheSolrForTypo3\Solr\Tests\Unit\UnitTest; +use Psr\Http\Message\UriInterface; +use TYPO3\CMS\Core\Site\Entity\Site; +use TYPO3\CMS\Core\Site\Entity\SiteLanguage; +use TYPO3\CMS\Core\Site\SiteFinder; /** * Testcase to check if the SiteHashService class works as expected. @@ -48,18 +51,34 @@ public function canResolveSiteHashAllowedSitesDataProvider() */ public function canResolveSiteHashAllowedSites($allowedSitesConfiguration, $expectedAllowedSites) { + $siteLanguageMock = $this->createMock(SiteLanguage::class); + $siteLanguageMock->method('getLanguageId')->willReturn(0); + + $siteConfiguration = ['solr_enabled_read' => 1, 'solr_core_read' => 'core_en']; + + $baseAMock = $this->createMock(UriInterface::class); + $baseAMock->method('getHost')->willReturn('solrtesta.local'); $siteA = $this->getDumbMock(Site::class); - $siteA->expects(self::any())->method('getDomain')->willReturn('solrtesta.local'); + $siteA->method('getBase')->willReturn($baseAMock); + $siteA->method('getLanguages')->willReturn([$siteLanguageMock]); + $siteA->method('getConfiguration')->willReturn($siteConfiguration); + + $baseBMock = $this->createMock(UriInterface::class); + $baseBMock->method('getHost')->willReturn('solrtestb.local'); $siteB = $this->getDumbMock(Site::class); - $siteB->expects(self::any())->method('getDomain')->willReturn('solrtestb.local'); + $siteB->method('getBase')->willReturn($baseBMock); + $siteB->method('getLanguages')->willReturn([$siteLanguageMock]); + $siteB->method('getConfiguration')->willReturn($siteConfiguration); + $allSites = [$siteA, $siteB]; - /** @var $siteHashServiceMock SiteHashService */ - $siteHashServiceMock = $this->getMockBuilder(SiteHashService::class)->onlyMethods(['getAvailableSites', 'getSiteByPageId'])->getMock(); - $siteHashServiceMock->expects(self::any())->method('getAvailableSites')->willReturn($allSites); - $siteHashServiceMock->expects(self::any())->method('getSiteByPageId')->willReturn($siteA); + $siteFinderMock = $this->createMock(SiteFinder::class); + $siteFinderMock->method('getAllSites')->willReturn($allSites); + $siteFinderMock->method('getSiteByPageId')->willReturn($siteA); + + $siteHashService = new SiteHashService($siteFinderMock); - $allowedSites = $siteHashServiceMock->getAllowedSitesForPageIdAndAllowedSitesConfiguration(1, $allowedSitesConfiguration); + $allowedSites = $siteHashService->getAllowedSitesForPageIdAndAllowedSitesConfiguration(1, $allowedSitesConfiguration); self::assertSame($expectedAllowedSites, $allowedSites, 'resolveSiteHashAllowedSites did not return expected allowed sites'); } @@ -71,7 +90,7 @@ public function getSiteHashForDomain() $oldKey = $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey']; $GLOBALS['TYPO3_CONF_VARS']['SYS']['encryptionKey'] = 'testKey'; - $service = new SiteHashService(); + $service = new SiteHashService($this->createMock(SiteFinder::class)); $hash1 = $service->getSiteHashForDomain('www.example.com'); $hash2 = $service->getSiteHashForDomain('www.example.com'); diff --git a/Tests/Unit/Query/Modifier/ElevationTest.php b/Tests/Unit/Query/Modifier/ElevationTest.php index 6cd9bbcc56..7d8a63fa11 100644 --- a/Tests/Unit/Query/Modifier/ElevationTest.php +++ b/Tests/Unit/Query/Modifier/ElevationTest.php @@ -17,6 +17,7 @@ use ApacheSolrForTypo3\Solr\Domain\Search\Query\Query; use ApacheSolrForTypo3\Solr\Domain\Search\Query\QueryBuilder; +use ApacheSolrForTypo3\Solr\Domain\Site\SiteHashService; use ApacheSolrForTypo3\Solr\Query\Modifier\Elevation; use ApacheSolrForTypo3\Solr\Tests\Unit\UnitTest; @@ -35,6 +36,7 @@ public function canModifyQuery() $query = $this->getDumbMock(Query::class); $queryBuilderMock = $this->getMockBuilder(QueryBuilder::class) + ->setConstructorArgs([null, null, $this->createMock(SiteHashService::class)]) ->disableProxyingToOriginalMethods() ->getMock(); $queryBuilderMock->expects(self::once())->method('startFrom')->willReturn($queryBuilderMock); diff --git a/Tests/Unit/Query/Modifier/FacetingTest.php b/Tests/Unit/Query/Modifier/FacetingTest.php index 526bb4a565..8a7b92f49a 100644 --- a/Tests/Unit/Query/Modifier/FacetingTest.php +++ b/Tests/Unit/Query/Modifier/FacetingTest.php @@ -25,6 +25,7 @@ use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets\InvalidUrlDecoderException; use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Facets\UrlFacetContainer; use ApacheSolrForTypo3\Solr\Domain\Search\SearchRequest; +use ApacheSolrForTypo3\Solr\Domain\Site\SiteHashService; use ApacheSolrForTypo3\Solr\Query\Modifier\Faceting; use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration; use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager; @@ -72,9 +73,15 @@ private function getQueryParametersFromExecutedFacetingModifier( $solrLogManagerMock = $this->getDumbMock(SolrLogManager::class); /* @var Query $query */ - $queryBuilder = new QueryBuilder($fakeConfiguration, $solrLogManagerMock); + $queryBuilder = new QueryBuilder( + $fakeConfiguration, + $solrLogManagerMock, + $this->createMock(SiteHashService::class) + ); $query = $queryBuilder->buildSearchQuery('test'); + GeneralUtility::addInstance(SiteHashService::class, $this->createMock(SiteHashService::class)); + /* @var Faceting $facetModifier */ $facetModifier = GeneralUtility::makeInstance(Faceting::class, $facetRegistry); $facetModifier->setSearchRequest($fakeSearchRequest); diff --git a/Tests/Unit/Search/RelevanceComponentTest.php b/Tests/Unit/Search/RelevanceComponentTest.php index abac93a306..6a596e7726 100644 --- a/Tests/Unit/Search/RelevanceComponentTest.php +++ b/Tests/Unit/Search/RelevanceComponentTest.php @@ -17,8 +17,10 @@ use ApacheSolrForTypo3\Solr\Domain\Search\Query\Query; use ApacheSolrForTypo3\Solr\Domain\Search\Query\QueryBuilder; +use ApacheSolrForTypo3\Solr\Domain\Site\SiteHashService; use ApacheSolrForTypo3\Solr\Search\RelevanceComponent; use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration; +use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager; use ApacheSolrForTypo3\Solr\Tests\Unit\UnitTest; use Solarium\QueryType\Select\RequestBuilder; @@ -55,7 +57,11 @@ public function canSetQuerySlop() ]; $typoscriptConfiguration = $this->getTypoScriptConfigurationWithQueryConfiguration($searchConfiguration); - $queryBuilder = new QueryBuilder($typoscriptConfiguration); + $queryBuilder = new QueryBuilder( + $typoscriptConfiguration, + $this->createMock(SolrLogManager::class), + $this->createMock(SiteHashService::class) + ); $relevanceComponent = new RelevanceComponent($queryBuilder); $query = new Query(); @@ -82,7 +88,11 @@ public function querySlopIsNotSetWhenPhraseIsDisabled() ], ]; $typoscriptConfiguration = $this->getTypoScriptConfigurationWithQueryConfiguration($searchConfiguration); - $queryBuilder = new QueryBuilder($typoscriptConfiguration); + $queryBuilder = new QueryBuilder( + $typoscriptConfiguration, + $this->createMock(SolrLogManager::class), + $this->createMock(SiteHashService::class) + ); $relevanceComponent = new RelevanceComponent($queryBuilder); $query = new Query(); @@ -110,7 +120,11 @@ public function canSetSlop() ]; $typoscriptConfiguration = $this->getTypoScriptConfigurationWithQueryConfiguration($searchConfiguration); - $queryBuilder = new QueryBuilder($typoscriptConfiguration); + $queryBuilder = new QueryBuilder( + $typoscriptConfiguration, + $this->createMock(SolrLogManager::class), + $this->createMock(SiteHashService::class) + ); $relevanceComponent = new RelevanceComponent($queryBuilder); $query = new Query(); @@ -137,7 +151,11 @@ public function slopIsNullWhenPhraseIsDisabled() ], ]; $typoscriptConfiguration = $this->getTypoScriptConfigurationWithQueryConfiguration($searchConfiguration); - $queryBuilder = new QueryBuilder($typoscriptConfiguration); + $queryBuilder = new QueryBuilder( + $typoscriptConfiguration, + $this->createMock(SolrLogManager::class), + $this->createMock(SiteHashService::class) + ); $relevanceComponent = new RelevanceComponent($queryBuilder); $query = new Query(); @@ -164,7 +182,11 @@ public function canSetBigramPhraseSlop() ], ]; $typoscriptConfiguration = $this->getTypoScriptConfigurationWithQueryConfiguration($searchConfiguration); - $queryBuilder = new QueryBuilder($typoscriptConfiguration); + $queryBuilder = new QueryBuilder( + $typoscriptConfiguration, + $this->createMock(SolrLogManager::class), + $this->createMock(SiteHashService::class) + ); $relevanceComponent = new RelevanceComponent($queryBuilder); $query = new Query(); @@ -192,7 +214,11 @@ public function canNotSetBigramPhraseSlopWhenBigramPhraseIsDisabled() ], ]; $typoscriptConfiguration = $this->getTypoScriptConfigurationWithQueryConfiguration($searchConfiguration); - $queryBuilder = new QueryBuilder($typoscriptConfiguration); + $queryBuilder = new QueryBuilder( + $typoscriptConfiguration, + $this->createMock(SolrLogManager::class), + $this->createMock(SiteHashService::class) + ); $relevanceComponent = new RelevanceComponent($queryBuilder); $query = new Query(); @@ -219,7 +245,11 @@ public function canSetTrigramPhraseSlop() ], ]; $typoscriptConfiguration = $this->getTypoScriptConfigurationWithQueryConfiguration($searchConfiguration); - $queryBuilder = new QueryBuilder($typoscriptConfiguration); + $queryBuilder = new QueryBuilder( + $typoscriptConfiguration, + $this->createMock(SolrLogManager::class), + $this->createMock(SiteHashService::class) + ); $relevanceComponent = new RelevanceComponent($queryBuilder); $query = new Query(); @@ -246,7 +276,11 @@ public function canNotSetTrigramPhraseSlopWhenBigramPhraseIsDisabled() ], ]; $typoscriptConfiguration = $this->getTypoScriptConfigurationWithQueryConfiguration($searchConfiguration); - $queryBuilder = new QueryBuilder($typoscriptConfiguration); + $queryBuilder = new QueryBuilder( + $typoscriptConfiguration, + $this->createMock(SolrLogManager::class), + $this->createMock(SiteHashService::class) + ); $relevanceComponent = new RelevanceComponent($queryBuilder); $query = new Query(); @@ -270,7 +304,11 @@ public function canSetTieParameter() ], ]; $typoscriptConfiguration = $this->getTypoScriptConfigurationWithQueryConfiguration($searchConfiguration); - $queryBuilder = new QueryBuilder($typoscriptConfiguration); + $queryBuilder = new QueryBuilder( + $typoscriptConfiguration, + $this->createMock(SolrLogManager::class), + $this->createMock(SiteHashService::class) + ); $relevanceComponent = new RelevanceComponent($queryBuilder); $query = new Query(); @@ -299,7 +337,11 @@ public function canSetBoostQuery() self::assertArrayNotHasKey('bq', $this->getQueryParameters($query)); $typoscriptConfiguration = $this->getTypoScriptConfigurationWithQueryConfiguration($searchConfiguration); - $queryBuilder = new QueryBuilder($typoscriptConfiguration); + $queryBuilder = new QueryBuilder( + $typoscriptConfiguration, + $this->createMock(SolrLogManager::class), + $this->createMock(SiteHashService::class) + ); $relevanceComponent = new RelevanceComponent($queryBuilder); $relevanceComponent->setSearchConfiguration($searchConfiguration); @@ -328,7 +370,11 @@ public function canSetBoostQueries() self::assertArrayNotHasKey('bq', $this->getQueryParameters($query)); $typoscriptConfiguration = $this->getTypoScriptConfigurationWithQueryConfiguration($searchConfiguration); - $queryBuilder = new QueryBuilder($typoscriptConfiguration); + $queryBuilder = new QueryBuilder( + $typoscriptConfiguration, + $this->createMock(SolrLogManager::class), + $this->createMock(SiteHashService::class) + ); $relevanceComponent = new RelevanceComponent($queryBuilder); $relevanceComponent->setSearchConfiguration($searchConfiguration); @@ -355,7 +401,11 @@ public function canSetBoostFunction() self::assertArrayNotHasKey('bf', $this->getQueryParameters($query)); $typoscriptConfiguration = $this->getTypoScriptConfigurationWithQueryConfiguration($searchConfiguration); - $queryBuilder = new QueryBuilder($typoscriptConfiguration); + $queryBuilder = new QueryBuilder( + $typoscriptConfiguration, + $this->createMock(SolrLogManager::class), + $this->createMock(SiteHashService::class) + ); $relevanceComponent = new RelevanceComponent($queryBuilder); $relevanceComponent->setSearchConfiguration($searchConfiguration); @@ -381,7 +431,11 @@ public function canSetMinimumMatch() self::assertArrayNotHasKey('mm', $this->getQueryParameters($query)); $typoscriptConfiguration = $this->getTypoScriptConfigurationWithQueryConfiguration($searchConfiguration); - $queryBuilder = new QueryBuilder($typoscriptConfiguration); + $queryBuilder = new QueryBuilder( + $typoscriptConfiguration, + $this->createMock(SolrLogManager::class), + $this->createMock(SiteHashService::class) + ); $relevanceComponent = new RelevanceComponent($queryBuilder); $relevanceComponent->setSearchConfiguration($searchConfiguration); diff --git a/Tests/Unit/Search/SortingComponentTest.php b/Tests/Unit/Search/SortingComponentTest.php index 2fa99a1d2b..9091c066dd 100644 --- a/Tests/Unit/Search/SortingComponentTest.php +++ b/Tests/Unit/Search/SortingComponentTest.php @@ -16,8 +16,12 @@ namespace ApacheSolrForTypo3\Solr\Tests\Unit\Search; use ApacheSolrForTypo3\Solr\Domain\Search\Query\Query; +use ApacheSolrForTypo3\Solr\Domain\Search\Query\QueryBuilder; use ApacheSolrForTypo3\Solr\Domain\Search\SearchRequest; +use ApacheSolrForTypo3\Solr\Domain\Site\SiteHashService; use ApacheSolrForTypo3\Solr\Search\SortingComponent; +use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration; +use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager; use ApacheSolrForTypo3\Solr\Tests\Unit\UnitTest; /** @@ -51,7 +55,13 @@ protected function setUp(): void $this->query->setQuery(''); $this->searchRequestMock = $this->getDumbMock(SearchRequest::class); - $this->sortingComponent = new SortingComponent(); + $queryBuilder = new QueryBuilder( + $this->createMock(TypoScriptConfiguration::class), + $this->createMock(SolrLogManager::class), + $this->createMock(SiteHashService::class) + ); + + $this->sortingComponent = new SortingComponent($queryBuilder); $this->sortingComponent->setQuery($this->query); $this->sortingComponent->setSearchRequest($this->searchRequestMock); parent::setUp();