Failed Conditions
Push — release-11.5.x ( 71e6eb...3bfdb1 )
by Markus
27:37
created

QueryBuilder::buildSearchQuery()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 25
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 18
CRAP Score 2.0005

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 18
c 1
b 0
f 0
dl 0
loc 25
ccs 18
cts 19
cp 0.9474
rs 9.6666
cc 2
nc 2
nop 3
crap 2.0005
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the TYPO3 CMS project.
7
 *
8
 * It is free software; you can redistribute it and/or modify it under
9
 * the terms of the GNU General Public License, either version 2
10
 * of the License, or any later version.
11
 *
12
 * For the full copyright and license information, please read the
13
 * LICENSE.txt file that was distributed with this source code.
14
 *
15
 * The TYPO3 project - inspiring people to share!
16
 */
17
18
namespace ApacheSolrForTypo3\Solr\Domain\Search\Query;
19
20
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\BigramPhraseFields;
21
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Elevation;
22
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Faceting;
23
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\FieldCollapsing;
24
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Filters;
25
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Grouping;
26
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Highlighting;
27
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\PhraseFields;
28
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\QueryFields;
29
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\ReturnFields;
30
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Slops;
31
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Sortings;
32
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Spellchecking;
33
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\TrigramPhraseFields;
34
use ApacheSolrForTypo3\Solr\Domain\Site\SiteHashService;
35
use ApacheSolrForTypo3\Solr\Domain\Site\SiteRepository;
36
use ApacheSolrForTypo3\Solr\FieldProcessor\PageUidToHierarchy;
37
use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration;
38
use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager;
39
use ApacheSolrForTypo3\Solr\Util;
40
use Doctrine\DBAL\Driver\Exception as DBALDriverException;
41
use Solarium\QueryType\Select\Query\Query as SolariumSelectQuery;
42
use Throwable;
43
use TYPO3\CMS\Core\Utility\GeneralUtility;
44
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
45
46
/**
47
 * The concrete QueryBuilder contains all TYPO3 specific initialization logic of solr queries, for TYPO3.
48
 *
49
 * @author Timo Hund <[email protected]>
50
 */
51
class QueryBuilder extends AbstractQueryBuilder
52
{
53
    /**
54
     * Additional filters, which will be added to the query, as well as to
55
     * suggest queries.
56
     *
57
     * @var array
58
     */
59
    protected array $additionalFilters = [];
60
61
    /**
62
     * @var TypoScriptConfiguration
63
     */
64
    protected TypoScriptConfiguration $typoScriptConfiguration;
65
66
    /**
67
     * @var SolrLogManager;
68
     */
69
    protected SolrLogManager $logger;
70
71
    /**
72
     * @var SiteHashService
73
     */
74
    protected SiteHashService $siteHashService;
75
76
    /**
77
     * QueryBuilder constructor.
78
     * @param TypoScriptConfiguration|null $configuration
79
     * @param SolrLogManager|null $solrLogManager
80
     * @param SiteHashService|null $siteHashService
81
     */
82 106
    public function __construct(
83
        TypoScriptConfiguration $configuration = null,
84
        SolrLogManager $solrLogManager = null,
85
        SiteHashService $siteHashService = null
86
    ) {
87 106
        $this->typoScriptConfiguration = $configuration ?? Util::getSolrConfiguration();
88 106
        $this->logger = $solrLogManager ?? GeneralUtility::makeInstance(SolrLogManager::class, /** @scrutinizer ignore-type */ __CLASS__);
89 106
        $this->siteHashService = $siteHashService ?? GeneralUtility::makeInstance(SiteHashService::class);
90
    }
91
92
    /**
93
     * @param string $queryString
94
     * @return QueryBuilder
95
     */
96 90
    public function newSearchQuery(string $queryString): QueryBuilder
97
    {
98 90
        $this->queryToBuild = $this->getSearchQueryInstance($queryString);
99 90
        return $this;
100
    }
101
102
    /**
103
     * @param string $queryString
104
     * @return QueryBuilder
105
     */
106 6
    public function newSuggestQuery(string $queryString): QueryBuilder
107
    {
108 6
        $this->queryToBuild = $this->getSuggestQueryInstance($queryString);
109 6
        return $this;
110
    }
111
112
    /**
113
     * Initializes the Query object and SearchComponents and returns
114
     * the initialized query object, when a search should be executed.
115
     *
116
     * @param string|null $rawQuery
117
     * @param int $resultsPerPage
118
     * @param array $additionalFiltersFromRequest
119
     * @return SolariumSelectQuery
120
     */
121 70
    public function buildSearchQuery(
122
        string $rawQuery = '',
123
        int $resultsPerPage = 10,
124
        array $additionalFiltersFromRequest = []
125
    ): SolariumSelectQuery {
126 70
        if ($this->typoScriptConfiguration->getLoggingQuerySearchWords()) {
127
            $this->logger->log(SolrLogManager::INFO, 'Received search query', [$rawQuery]);
128
        }
129
130 70
        return $this->newSearchQuery($rawQuery)
131 70
                ->useResultsPerPage($resultsPerPage)
132 70
                ->useReturnFieldsFromTypoScript()
133 70
                ->useQueryFieldsFromTypoScript()
134 70
                ->useInitialQueryFromTypoScript()
135 70
                ->useFiltersFromTypoScript()
136 70
                ->useFilterArray($additionalFiltersFromRequest)
137 70
                ->useFacetingFromTypoScript()
138 70
                ->useVariantsFromTypoScript()
139 70
                ->useGroupingFromTypoScript()
140 70
                ->useHighlightingFromTypoScript()
141 70
                ->usePhraseFieldsFromTypoScript()
142 70
                ->useBigramPhraseFieldsFromTypoScript()
143 70
                ->useTrigramPhraseFieldsFromTypoScript()
144 70
                ->useOmitHeader(false)
145 70
                ->getQuery();
146
    }
147
148
    /**
149
     * Builds a SuggestQuery with all applied filters.
150
     *
151
     * @param string $queryString
152
     * @param array $additionalFilters
153
     * @param int $requestedPageId
154
     * @param string $groupList
155
     * @return SuggestQuery
156
     * @throws DBALDriverException
157
     * @throws Throwable
158
     */
159 6
    public function buildSuggestQuery(string $queryString, array $additionalFilters, int $requestedPageId, string $groupList): SuggestQuery
160
    {
161 6
        $this->newSuggestQuery($queryString)
162 6
            ->useFiltersFromTypoScript()
163 6
            ->useSiteHashFromTypoScript($requestedPageId)
164 6
            ->useUserAccessGroups(explode(',', $groupList))
165 6
            ->useOmitHeader();
166
167 6
        if (!empty($additionalFilters)) {
168
            $this->useFilterArray($additionalFilters);
169
        }
170
171 6
        return $this->queryToBuild;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->queryToBuild returns the type null which is incompatible with the type-hinted return ApacheSolrForTypo3\Solr\...arch\Query\SuggestQuery.
Loading history...
172
    }
173
174
    /**
175
     * Returns Query for Search which finds document for given page.
176
     * Note: The Connection is per language as recommended in ext-solr docs.
177
     *
178
     * @param int $pageId
179
     * @return SolariumSelectQuery
180
     * @throws DBALDriverException
181
     */
182 2
    public function buildPageQuery(int $pageId): SolariumSelectQuery
183
    {
184 2
        $siteRepository = GeneralUtility::makeInstance(SiteRepository::class);
185 2
        $site = $siteRepository->getSiteByPageId($pageId);
186
187 2
        return $this->newSearchQuery('')
188 2
            ->useQueryString('*:*')
189 2
            ->useFilter('(type:pages AND uid:' . $pageId . ') OR (*:* AND pid:' . $pageId . ' NOT type:pages)', 'type')
190 2
            ->useFilter('siteHash:' . $site->getSiteHash(), 'siteHash')
191 2
            ->useReturnFields(ReturnFields::fromString('*'))
192 2
            ->useSortings(Sortings::fromString('type asc, title asc'))
193 2
            ->useQueryType('standard')
194 2
            ->getQuery();
195
    }
196
197
    /**
198
     * Returns a query for single record
199
     *
200
     * @param string $type
201
     * @param int $uid
202
     * @param int $pageId
203
     * @return SolariumSelectQuery|Query
204
     * @throws DBALDriverException
205
     */
206
    public function buildRecordQuery(string $type, int $uid, int $pageId): SolariumSelectQuery
207
    {
208
        $siteRepository = GeneralUtility::makeInstance(SiteRepository::class);
209
        $site = $siteRepository->getSiteByPageId($pageId);
210
211
        return $this->newSearchQuery('')
212
            ->useQueryString('*:*')
213
            ->useFilter('type:' . $type . ' AND uid:' . $uid, 'type')
214
            ->useFilter('siteHash:' . $site->getSiteHash(), 'siteHash')
215
            ->useReturnFields(ReturnFields::fromString('*'))
216
            ->useSortings(Sortings::fromString('type asc, title asc'))
217
            ->useQueryType('standard')
218
            ->getQuery();
219
    }
220
221
    /**
222
     * @return QueryBuilder
223
     */
224 70
    public function useSlopsFromTypoScript(): QueryBuilder
225
    {
226 70
        return $this->useSlops(Slops::fromTypoScriptConfiguration($this->typoScriptConfiguration));
227
    }
228
229
    /**
230
     * Uses the configured boost queries from typoscript
231
     *
232
     * @return QueryBuilder
233
     */
234 70
    public function useBoostQueriesFromTypoScript(): QueryBuilder
235
    {
236 70
        $searchConfiguration = $this->typoScriptConfiguration->getSearchConfiguration();
237
238 70
        if (!empty($searchConfiguration['query.']['boostQuery'])) {
239
            return $this->useBoostQueries($searchConfiguration['query.']['boostQuery']);
240
        }
241
242 70
        if (!empty($searchConfiguration['query.']['boostQuery.'])) {
243
            $boostQueries = $searchConfiguration['query.']['boostQuery.'];
244
            return $this->useBoostQueries(array_values($boostQueries));
245
        }
246
247 70
        return $this;
248
    }
249
250
    /**
251
     * Uses the configured boostFunction from the typoscript configuration.
252
     *
253
     * @return QueryBuilder
254
     */
255 70
    public function useBoostFunctionFromTypoScript(): QueryBuilder
256
    {
257 70
        $searchConfiguration = $this->typoScriptConfiguration->getSearchConfiguration();
258 70
        if (!empty($searchConfiguration['query.']['boostFunction'])) {
259
            return $this->useBoostFunction($searchConfiguration['query.']['boostFunction']);
260
        }
261
262 70
        return $this;
263
    }
264
265
    /**
266
     * Uses the configured minimumMatch from the typoscript configuration.
267
     *
268
     * @return QueryBuilder
269
     */
270 70
    public function useMinimumMatchFromTypoScript(): QueryBuilder
271
    {
272 70
        $searchConfiguration = $this->typoScriptConfiguration->getSearchConfiguration();
273 70
        if (!empty($searchConfiguration['query.']['minimumMatch'])) {
274
            return $this->useMinimumMatch($searchConfiguration['query.']['minimumMatch']);
275
        }
276
277 70
        return $this;
278
    }
279
280
    /**
281
     * @return QueryBuilder
282
     */
283 70
    public function useTieParameterFromTypoScript(): QueryBuilder
284
    {
285 70
        $searchConfiguration = $this->typoScriptConfiguration->getSearchConfiguration();
286 70
        if (empty($searchConfiguration['query.']['tieParameter'])) {
287 70
            return $this;
288
        }
289
290
        return $this->useTieParameter((float)$searchConfiguration['query.']['tieParameter']);
291
    }
292
293
    /**
294
     * Applies the configured query fields from the typoscript configuration.
295
     *
296
     * @return QueryBuilder
297
     */
298 70
    public function useQueryFieldsFromTypoScript(): QueryBuilder
299
    {
300 70
        return $this->useQueryFields(QueryFields::fromString($this->typoScriptConfiguration->getSearchQueryQueryFields()));
301
    }
302
303
    /**
304
     * Applies the configured return fields from the typoscript configuration.
305
     *
306
     * @return QueryBuilder
307
     */
308 70
    public function useReturnFieldsFromTypoScript(): QueryBuilder
309
    {
310 70
        $returnFieldsArray = $this->typoScriptConfiguration->getSearchQueryReturnFieldsAsArray(['*', 'score']);
311 70
        return $this->useReturnFields(ReturnFields::fromArray($returnFieldsArray));
312
    }
313
314
    /**
315
     * Can be used to apply the allowed sites from plugin.tx_solr.search.query.allowedSites to the query.
316
     *
317
     * @param int $requestedPageId
318
     * @return QueryBuilder
319
     * @throws DBALDriverException
320
     * @throws Throwable
321
     */
322 70
    public function useSiteHashFromTypoScript(int $requestedPageId): QueryBuilder
323
    {
324 70
        $queryConfiguration = $this->typoScriptConfiguration->getObjectByPathOrDefault('plugin.tx_solr.search.query.', []);
325 70
        $allowedSites = $this->siteHashService->getAllowedSitesForPageIdAndAllowedSitesConfiguration($requestedPageId, $queryConfiguration['allowedSites']);
326 70
        return $this->useSiteHashFromAllowedSites($allowedSites);
327
    }
328
329
    /**
330
     * Can be used to apply a list of allowed sites to the query.
331
     *
332
     * @param string $allowedSites
333
     * @return QueryBuilder
334
     */
335 70
    public function useSiteHashFromAllowedSites(string $allowedSites): QueryBuilder
336
    {
337 70
        $isAnySiteAllowed = trim($allowedSites) === '*';
338 70
        if ($isAnySiteAllowed) {
339
            // no filter required
340
            return $this;
341
        }
342
343 70
        $allowedSites = GeneralUtility::trimExplode(',', $allowedSites);
344 70
        $filters = [];
345 70
        foreach ($allowedSites as $site) {
346 70
            $siteHash = $this->siteHashService->getSiteHashForDomain($site);
347 70
            $filters[] = 'siteHash:"' . $siteHash . '"';
348
        }
349
350 70
        $siteHashFilterString = implode(' OR ', $filters);
351 70
        return $this->useFilter($siteHashFilterString, 'siteHash');
352
    }
353
354
    /**
355
     * Can be used to filter the result on an applied list of user groups.
356
     *
357
     * @param array $groups
358
     * @return QueryBuilder
359
     */
360 70
    public function useUserAccessGroups(array $groups): QueryBuilder
361
    {
362 70
        $groups = array_map('intval', $groups);
363 70
        $groups[] = 0; // always grant access to public documents
364 70
        $groups = array_unique($groups);
365 70
        sort($groups, SORT_NUMERIC);
366
367 70
        $accessFilter = '{!typo3access}' . implode(',', $groups);
368 70
        $this->queryToBuild->removeFilterQuery('access');
0 ignored issues
show
Bug introduced by
The method removeFilterQuery() does not exist on null. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

368
        $this->queryToBuild->/** @scrutinizer ignore-call */ 
369
                             removeFilterQuery('access');

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
369 70
        return $this->useFilter($accessFilter, 'access');
370
    }
371
372
    /**
373
     * Applies the configured initial query settings to set the alternative query for solr as required.
374
     *
375
     * @return QueryBuilder
376
     */
377 70
    public function useInitialQueryFromTypoScript(): QueryBuilder
378
    {
379 70
        if ($this->typoScriptConfiguration->getSearchInitializeWithEmptyQuery() || $this->typoScriptConfiguration->getSearchQueryAllowEmptyQuery()) {
380
            // empty main query, but using a "return everything"
381
            // alternative query in q.alt
382 16
            $this->useAlternativeQuery('*:*');
383
        }
384
385 70
        if ($this->typoScriptConfiguration->getSearchInitializeWithQuery()) {
386 4
            $this->useAlternativeQuery($this->typoScriptConfiguration->getSearchInitializeWithQuery());
387
        }
388
389 70
        return $this;
390
    }
391
392
    /**
393
     * Applies the configured facets from the typoscript configuration on the query.
394
     *
395
     * @return QueryBuilder
396
     */
397 70
    public function useFacetingFromTypoScript(): QueryBuilder
398
    {
399 70
        return $this->useFaceting(Faceting::fromTypoScriptConfiguration($this->typoScriptConfiguration));
400
    }
401
402
    /**
403
     * Applies the configured variants from the typoscript configuration on the query.
404
     *
405
     * @return QueryBuilder
406
     */
407 70
    public function useVariantsFromTypoScript(): QueryBuilder
408
    {
409 70
        return $this->useFieldCollapsing(FieldCollapsing::fromTypoScriptConfiguration($this->typoScriptConfiguration));
410
    }
411
412
    /**
413
     * Applies the configured groupings from the typoscript configuration to the query.
414
     *
415
     * @return QueryBuilder
416
     */
417 70
    public function useGroupingFromTypoScript(): QueryBuilder
418
    {
419 70
        return $this->useGrouping(Grouping::fromTypoScriptConfiguration($this->typoScriptConfiguration));
420
    }
421
422
    /**
423
     * Applies the configured highlighting from the typoscript configuration to the query.
424
     *
425
     * @return QueryBuilder
426
     */
427 70
    public function useHighlightingFromTypoScript(): QueryBuilder
428
    {
429 70
        return $this->useHighlighting(Highlighting::fromTypoScriptConfiguration($this->typoScriptConfiguration));
430
    }
431
432
    /**
433
     * Applies the configured filters (page section and other from typoscript).
434
     *
435
     * @return QueryBuilder
436
     * @todo: Method is widely used but {@link Filters::fromTypoScriptConfiguration()} does not take TypoScript into account
437
     */
438 70
    public function useFiltersFromTypoScript(): QueryBuilder
439
    {
440 70
        $filters = Filters::fromTypoScriptConfiguration($this->typoScriptConfiguration);
441 70
        $this->queryToBuild->setFilterQueries($filters->getValues());
442
443 70
        $this->useFilterArray($this->getAdditionalFilters());
444
445 70
        $searchQueryFilters = $this->typoScriptConfiguration->getSearchQueryFilterConfiguration();
446
447 70
        if (count($searchQueryFilters) <= 0) {
448 64
            return $this;
449
        }
450
451
        // special filter to limit search to specific page tree branches
452 6
        if (array_key_exists('__pageSections', $searchQueryFilters)) {
453 2
            if ($searchQueryFilters['__pageSections.'] ?? false) {
454
                $cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class);
455
                $searchQueryFilters['__pageSections'] = $cObj->stdWrap(
456
                    $searchQueryFilters['__pageSections'],
457
                    $searchQueryFilters['__pageSections.']
458
                );
459
            }
460 2
            $pageIds = GeneralUtility::trimExplode(',', $searchQueryFilters['__pageSections']);
461 2
            $this->usePageSectionsFromPageIds($pageIds);
462 2
            $this->typoScriptConfiguration->removeSearchQueryFilterForPageSections();
463
        }
464
465 6
        return $this;
466
    }
467
468
    /**
469
     * Applies the configured elevation from the typoscript configuration.
470
     *
471
     * @return QueryBuilder
472
     */
473 70
    public function useElevationFromTypoScript(): QueryBuilder
474
    {
475 70
        return $this->useElevation(Elevation::fromTypoScriptConfiguration($this->typoScriptConfiguration));
476
    }
477
478
    /**
479
     * Applies the configured spellchecking from the typoscript configuration.
480
     *
481
     * @return QueryBuilder
482
     */
483 4
    public function useSpellcheckingFromTypoScript(): QueryBuilder
484
    {
485 4
        return $this->useSpellchecking(Spellchecking::fromTypoScriptConfiguration($this->typoScriptConfiguration));
486
    }
487
488
    /**
489
     * Applies the passed pageIds as __pageSection filter.
490
     *
491
     * @param array $pageIds
492
     * @return QueryBuilder
493
     */
494 2
    public function usePageSectionsFromPageIds(array $pageIds = []): QueryBuilder
495
    {
496 2
        $filters = [];
497
498
        /** @var $processor PageUidToHierarchy */
499 2
        $processor = GeneralUtility::makeInstance(PageUidToHierarchy::class);
500 2
        $hierarchies = $processor->process($pageIds);
501
502 2
        foreach ($hierarchies as $hierarchy) {
503 2
            $lastLevel = array_pop($hierarchy);
504 2
            $filters[] = 'rootline:"' . $lastLevel . '"';
505
        }
506
507 2
        $pageSectionsFilterString = implode(' OR ', $filters);
508 2
        return $this->useFilter($pageSectionsFilterString, 'pageSections');
509
    }
510
511
    /**
512
     * Applies the configured phrase fields from the typoscript configuration to the query.
513
     *
514
     * @return QueryBuilder
515
     */
516 70
    public function usePhraseFieldsFromTypoScript(): QueryBuilder
517
    {
518 70
        return $this->usePhraseFields(PhraseFields::fromTypoScriptConfiguration($this->typoScriptConfiguration));
519
    }
520
521
    /**
522
     * Applies the configured bigram phrase fields from the typoscript configuration to the query.
523
     *
524
     * @return QueryBuilder
525
     */
526 70
    public function useBigramPhraseFieldsFromTypoScript(): QueryBuilder
527
    {
528 70
        return $this->useBigramPhraseFields(BigramPhraseFields::fromTypoScriptConfiguration($this->typoScriptConfiguration));
529
    }
530
531
    /**
532
     * Applies the configured trigram phrase fields from the typoscript configuration to the query.
533
     *
534
     * @return QueryBuilder
535
     */
536 70
    public function useTrigramPhraseFieldsFromTypoScript(): QueryBuilder
537
    {
538 70
        return $this->useTrigramPhraseFields(TrigramPhraseFields::fromTypoScriptConfiguration($this->typoScriptConfiguration));
539
    }
540
541
    /**
542
     * Retrieves the configuration filters from the TypoScript configuration, except the __pageSections filter.
543
     *
544
     * @return array
545
     */
546 70
    public function getAdditionalFilters(): array
547
    {
548
        // when we've built the additionalFilter once, we could return them
549 70
        if (count($this->additionalFilters) > 0) {
550 4
            return $this->additionalFilters;
551
        }
552
553 70
        $searchQueryFilters = $this->typoScriptConfiguration->getSearchQueryFilterConfiguration();
554 70
        if (count($searchQueryFilters) <= 0) {
555 66
            return [];
556
        }
557
558 6
        $cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class);
559
560
        // all other regular filters
561 6
        foreach ($searchQueryFilters as $filterKey => $filter) {
562
            // the __pageSections filter should not be handled as additional filter
563 6
            if ($filterKey === '__pageSections') {
564 2
                continue;
565
            }
566
567 4
            $filterIsArray = isset($searchQueryFilters[$filterKey]) && is_array($searchQueryFilters[$filterKey]);
568 4
            if ($filterIsArray) {
569
                continue;
570
            }
571
572 4
            $hasSubConfiguration = isset($searchQueryFilters[$filterKey . '.']) && is_array($searchQueryFilters[$filterKey . '.']);
573 4
            if ($hasSubConfiguration) {
574
                $filter = $cObj->stdWrap($searchQueryFilters[$filterKey], $searchQueryFilters[$filterKey . '.']);
575
            }
576
577 4
            $this->additionalFilters[$filterKey] = $filter;
578
        }
579
580 6
        return $this->additionalFilters;
581
    }
582
583
    /**
584
     * @param string $rawQuery
585
     * @return SearchQuery
586
     */
587 90
    protected function getSearchQueryInstance(string $rawQuery): SearchQuery
588
    {
589 90
        $query = GeneralUtility::makeInstance(SearchQuery::class);
590 90
        $query->setQuery($rawQuery);
591 90
        return $query;
592
    }
593
594
    /**
595
     * @param string $rawQuery
596
     * @return SuggestQuery
597
     */
598 6
    protected function getSuggestQueryInstance(string $rawQuery): SuggestQuery
599
    {
600 6
        return GeneralUtility::makeInstance(SuggestQuery::class, /** @scrutinizer ignore-type */ $rawQuery, /** @scrutinizer ignore-type */ $this->typoScriptConfiguration);
601
    }
602
}
603