Passed
Push — master ( 982e46...a8ac91 )
by Timo
19:05
created

Query::getId()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 2
cts 2
cp 1
cc 1
eloc 2
nc 1
nop 0
crap 1
1
<?php
2
namespace ApacheSolrForTypo3\Solr;
3
4
/***************************************************************
5
 *  Copyright notice
6
 *
7
 *  (c) 2009-2015 Ingo Renner <[email protected]>
8
 *  All rights reserved
9
 *
10
 *  This script is part of the TYPO3 project. The TYPO3 project is
11
 *  free software; you can redistribute it and/or modify
12
 *  it under the terms of the GNU General Public License as published by
13
 *  the Free Software Foundation; either version 2 of the License, or
14
 *  (at your option) any later version.
15
 *
16
 *  The GNU General Public License can be found at
17
 *  http://www.gnu.org/copyleft/gpl.html.
18
 *
19
 *  This script is distributed in the hope that it will be useful,
20
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
21
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
22
 *  GNU General Public License for more details.
23
 *
24
 *  This copyright notice MUST APPEAR in all copies of the script!
25
 ***************************************************************/
26
27
use ApacheSolrForTypo3\Solr\Domain\Search\Query\Helper\EscapeService;
28
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Faceting;
29
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Filters;
30
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Grouping;
31
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Highlighting;
32
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\QueryFields;
33
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\ReturnFields;
34
use ApacheSolrForTypo3\Solr\Domain\Site\SiteHashService;
35
use ApacheSolrForTypo3\Solr\FieldProcessor\PageUidToHierarchy;
36
use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration;
37
use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager;
38
use TYPO3\CMS\Core\Utility\GeneralUtility;
39
40
/**
41
 * A Solr search query
42
 *
43
 * @author Ingo Renner <[email protected]>
44
 * @author Timo Hund <[email protected]>
45
 */
46
class Query
47
{
48
49
    // FIXME extract link building from the query, it's not the query's domain
50
51
    const SORT_ASC = 'ASC';
52
    const SORT_DESC = 'DESC';
53
54
    const OPERATOR_AND = 'AND';
55
    const OPERATOR_OR = 'OR';
56
57
    /**
58
     * Used to identify the queries.
59
     *
60
     * @var int
61
     */
62
    protected static $idCount = 0;
63
64
    /**
65
     * @var int
66
     */
67
    protected $id;
68
69
    /**
70
     * @var TypoScriptConfiguration
71
     */
72
    protected $solrConfiguration;
73
74
    /**
75
     * @var string
76
     */
77
    protected $keywords;
78
79
    /**
80
     * @var string
81
     */
82
    protected $keywordsRaw;
83
84
    /**
85
     * ParameterBuilder for filters.
86
     *
87
     * @var Filters
88
     */
89
    protected $filters = null;
90
91
    /**
92
     * @var string
93
     */
94
    protected $sorting;
95
96
    // TODO check usage of these two variants, especially the check for $rawQueryString in getQueryString()
97
    /**
98
     * @var
99
     */
100
    protected $queryString;
101
102
    /**
103
     * @var array
104
     */
105
    protected $queryParameters = [];
106
107
    /**
108
     * @var int
109
     */
110
    protected $resultsPerPage;
111
112
    /**
113
     * @var int
114
     */
115
    protected $page;
116
117
    /**
118
     * @var int
119
     */
120
    protected $linkTargetPageId;
121
122
    /**
123
     * Holds the query fields with their associated boosts. The key represents
124
     * the field name, value represents the field's boost. These are the fields
125
     * that will actually be searched.
126
     *
127
     * Used in Solr's qf parameter
128
     *
129
     * @var QueryFields
130
     * @see http://wiki.apache.org/solr/DisMaxQParserPlugin#qf_.28Query_Fields.29
131
     */
132
    protected $queryFields = null;
133
134
    /**
135
     * List of fields that will be returned in the result documents.
136
     *
137
     * used in Solr's fl parameter
138
     *
139
     * @var ReturnFields
140
     * @see http://wiki.apache.org/solr/CommonQueryParameters#fl
141
     */
142
    protected $returnFields = null;
143
144
    /**
145
     * ParameterBuilder for the highlighting.
146
     *
147
     * @var Highlighting
148
     */
149
    protected $highlighting = null;
150
151
    /**
152
     * ParameterBuilder for the faceting.
153
     *
154
     * @var Faceting
155
     */
156
    protected $faceting = null;
157
158
    /**
159
     * ParameterBuilder for the grouping.
160
     *
161
     * @var Grouping
162
     */
163
    protected $grouping = null;
164
165
    /**
166 125
     * @var bool
167
     */
168 125
    private $rawQueryString = false;
169
170 125
    /**
171 125
     * The field by which the result will be collapsed
172 125
     * @var string
173
     */
174 125
    protected $variantField = 'variantId';
175 125
176
    /**
177
     * @var SiteHashService
178 125
     */
179 125
    protected $siteHashService = null;
180 30
181
    /**
182
     * @var \ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager
183
     */
184 125
    protected $logger = null;
185 125
186
    /**
187 125
     * @var EscapeService
188
     */
189 125
    protected $escapeService = null;
190 125
191
    /**
192
     * Query constructor.
193
     * @param string $keywords
194
     * @param TypoScriptConfiguration $solrConfiguration
195 124
     * @param SiteHashService|null $siteHashService
196
     * @param EscapeService|null $escapeService
197 124
     */
198 124
    public function __construct($keywords, $solrConfiguration = null, SiteHashService $siteHashService = null, EscapeService $escapeService = null)
199
    {
200
        $keywords = (string)$keywords;
201
202
        $this->logger = GeneralUtility::makeInstance(SolrLogManager::class, __CLASS__);
203
        $this->solrConfiguration = is_null($solrConfiguration) ? Util::getSolrConfiguration() : $solrConfiguration;
204
        $this->siteHashService = is_null($siteHashService) ? GeneralUtility::makeInstance(SiteHashService::class) : $siteHashService;
205
        $this->escapeService = is_null($escapeService) ? GeneralUtility::makeInstance(EscapeService::class) : $escapeService;
206
        $this->setKeywords($keywords);
207
        $this->sorting = '';
208
209
        $this->linkTargetPageId = $this->solrConfiguration->getSearchTargetPage();
210
211
        $this->initializeQuery();
212
213 31
        $this->id = ++self::$idCount;
214
    }
215 31
216
    /**
217 31
     * @return void
218 31
     */
219
    protected function initializeQuery()
220 31
    {
221 31
        // Filters
222 31
        $this->initializeFilters();
223
224
        // What fields to search
225 31
        $queryFields = QueryFields::fromString($this->solrConfiguration->getSearchQueryQueryFields());
226
        $this->setQueryFields($queryFields);
227 31
228
        // What fields to return from Solr
229
        $returnFieldsArray = $this->solrConfiguration->getSearchQueryReturnFieldsAsArray(['*', 'score']);
230
        $returnFields = ReturnFields::fromArray($returnFieldsArray);
231
        $this->setReturnFields($returnFields);
232
233
        // Configure highlighting
234
        $highlighting = Highlighting::fromTypoScriptConfiguration($this->solrConfiguration);
235
        $this->setHighlighting($highlighting);
236
237
        // Configure faceting
238 31
        $this->initializeFaceting();
239
240 31
        // Initialize grouping
241 31
        $this->initializeGrouping();
242
243
        // Configure collapsing
244
        $this->initializeCollapsingFromConfiguration();
245
    }
246
247
    /**
248
     * Takes a string of comma separated query fields and _overwrites_ the
249
     * currently set query fields. Boost can also be specified in through the
250
     * given string.
251
     *
252
     * Example: "title^5, subtitle^2, content, author^0.5"
253
     * This sets the query fields to title with  a boost of 5.0, subtitle with
254
     * a boost of 2.0, content with a default boost of 1.0 and the author field
255
     * with a boost of 0.5
256
     *
257
     * @deprecated use setQueryFields with QueryFields instead, will be removed in 8.0
258
     * @param string $queryFields A string defining which fields to query and their associated boosts
259 8
     * @return void
260
     */
261 8
    public function setQueryFieldsFromString($queryFields)
262
    {
263
        GeneralUtility::logDeprecatedFunction();
264
        $this->setQueryFields(QueryFields::fromString($queryFields));
265
    }
266
267
    /**
268
     * Sets a query field and its boost. If the field does not exist yet, it
269 41
     * gets added. Boost is optional, if left out a default boost of 1.0 is
270
     * applied.
271 41
     *
272 38
     * @deprecated use getQueryFields()->set($fieldName, $boost) instead, will be removed in 8.0
273
     * @param string $fieldName The field's name
274
     * @param float $boost Optional field boost, defaults to 1.0
275 41
     * @return void
276
     */
277
    public function setQueryField($fieldName, $boost = 1.0)
278
    {
279
        GeneralUtility::logDeprecatedFunction();
280
        $this->getQueryFields()->set($fieldName, $boost);
281
    }
282
283
    /**
284
     * @param QueryFields $queryFields
285
     */
286 4
    public function setQueryFields(QueryFields $queryFields)
287
    {
288 4
        $this->queryFields = $queryFields;
289 4
    }
290
291
    /**
292
     * @return QueryFields
293
     */
294
    public function getQueryFields()
295
    {
296 38
        return $this->queryFields;
297
    }
298
299 38
    /**
300 38
     * magic implementation for clone(), makes sure that the id counter is
301
     * incremented
302
     *
303
     * @return void
304
     */
305
    public function __clone()
306
    {
307
        $this->id = ++self::$idCount;
308 4
    }
309
310 4
    /**
311 4
     * returns a string representation of the query
312
     *
313
     * @return string the string representation of the query
314
     */
315
    public function __toString()
316
    {
317
        return $this->getQueryString();
318
    }
319
320
    /**
321
     * Builds the query string which is then used for Solr's q parameters
322
     *
323
     * @return string Solr query string
324
     */
325
    public function getQueryString()
326
    {
327
        if (!$this->rawQueryString) {
328
            $this->buildQueryString();
329 125
        }
330
331
        return $this->queryString;
332 125
    }
333 1
334
    /**
335
     * Sets the query string without any escaping.
336
     *
337 125
     * Be cautious with this function!
338 93
     * TODO remove this method as it basically just sets the q parameter / keywords
339
     *
340
     * @param string $queryString The raw query string.
341
     */
342 48
    public function setQueryString($queryString)
343 48
    {
344 41
        $this->queryString = $queryString;
345
    }
346
347 7
    /**
348
     * Creates the string that is later used as the q parameter in the solr query
349 7
     *
350
     * @return void
351
     */
352
    protected function buildQueryString()
353
    {
354
        // very simple for now
355
        $this->queryString = $this->keywords;
356
    }
357
358
    /**
359 7
     * Sets whether a raw query sting should be used, that is, whether the query
360
     * string should be escaped or not.
361 7
     *
362 7
     * @param bool $useRawQueryString TRUE to use raw queries (like Lucene Query Language) or FALSE for regular, escaped queries
363 7
     */
364
    public function useRawQueryString($useRawQueryString)
365
    {
366
        $this->rawQueryString = (boolean)$useRawQueryString;
367 7
    }
368 7
369 7
    /**
370 7
     * Returns the query's ID.
371 7
     *
372
     * @return int The query's ID.
373 7
     */
374 1
    public function getId()
375
    {
376
        return $this->id;
377 7
    }
378 6
379
    /**
380 7
     * Quote and escape search strings
381
     *
382
     * @param string $string String to escape
383 7
     * @deprecated Please use EscapeService noew, will be removed in 8.0
384
     * @return string The escaped/quoted string
385
     */
386 7
    public function escape($string)
387
    {
388
        GeneralUtility::logDeprecatedFunction();
389
            /** @var EscapeService $escapeService */
390
        $escapeService = GeneralUtility::makeInstance(EscapeService::class);
391
        return $escapeService->escape($string);
392
    }
393
394
    /**
395
     * Gets the currently showing page's number
396
     *
397
     * @return int page number currently showing
398 6
     */
399
    public function getPage()
400 6
    {
401 6
        return $this->page;
402
    }
403 6
404
    /**
405
     * Sets the page that should be shown
406
     *
407
     * @param int $page page number to show
408
     * @return void
409
     */
410
    public function setPage($page)
411
    {
412 125
        $this->page = max(intval($page), 0);
413
    }
414
415
    /**
416
     * Gets the index of the first result document we're showing
417
     *
418 125
     * @return int index of the currently first document showing
419 125
     */
420
    public function getStartIndex()
421 125
    {
422
        return ($this->page - 1) * $this->resultsPerPage;
423
    }
424
425
    /**
426
     * Gets the index of the last result document we're showing
427
     *
428
     * @return int index of the currently last document showing
429 1
     */
430
    public function getEndIndex()
431 1
    {
432
        return $this->page * $this->resultsPerPage;
433
    }
434
435
    // query elevation
436
437
    /**
438
     * Activates and deactivates query elevation for the current query.
439
     *
440 1
     * @param bool $elevation True to enable query elevation (default), FALSE to disable query elevation.
441
     * @param bool $forceElevation Optionally force elevation so that the elevated documents are always on top regardless of sorting, default to TRUE.
442 1
     * @param bool $markElevatedResults Mark elevated results
443 1
     * @return void
444
     */
445
    public function setQueryElevation($elevation = true, $forceElevation = true, $markElevatedResults = true)
446
    {
447
        if ($elevation) {
448
            $this->queryParameters['enableElevation'] = 'true';
449
            $this->setForceElevation($forceElevation);
450
            if ($markElevatedResults) {
451
                $this->getReturnFields()->add('isElevated:[elevated]');
452
            }
453
        } else {
454
            $this->queryParameters['enableElevation'] = 'false';
455
            unset($this->queryParameters['forceElevation']);
456
            $this->getReturnFields()->remove('isElevated:[elevated]');
457
            $this->getReturnFields()->remove('[elevated]'); // fallback
458
        }
459
    }
460
461
    /**
462
     * Enables or disables the forceElevation query parameter.
463
     *
464
     * @param bool $forceElevation
465
     */
466
    protected function setForceElevation($forceElevation)
467
    {
468
        if ($forceElevation) {
469
            $this->queryParameters['forceElevation'] = 'true';
470
        } else {
471
            $this->queryParameters['forceElevation'] = 'false';
472
        }
473
    }
474
475 28
    // collapsing
476
477
    /**
478
     * Check whether collapsing is active
479
     *
480 28
     * @return bool
481 24
     */
482 24
    public function getIsCollapsing()
483 24
    {
484 24
        return $this->getFilters()->hasWithName('collapsing');
485
    }
486
487 5
    /**
488 5
     * @param string $fieldName
489 5
     */
490 5
    public function setVariantField($fieldName)
491
    {
492 28
        $this->variantField = $fieldName;
493
    }
494
495
    /**
496
     * @return string
497
     */
498
    public function getVariantField()
499 24
    {
500
        return $this->variantField;
501 24
    }
502 23
503
    /**
504 1
     * @param bool $collapsing
505
     */
506 24
    public function setCollapsing($collapsing = true)
507
    {
508
        if ($collapsing) {
509
            $this->getFilters()->add('{!collapse field=' . $this->variantField . '}', 'collapsing');
510
            if ($this->solrConfiguration->getSearchVariantsExpand()) {
511
                $this->queryParameters['expand'] = 'true';
512
                $this->queryParameters['expand.rows'] = $this->solrConfiguration->getSearchVariantsLimit();
513
            }
514
        } else {
515 3
            $this->getFilters()->removeByName('collapsing');
516
            unset($this->queryParameters['expand']);
517 3
            unset($this->queryParameters['expand.rows']);
518
        }
519
    }
520
521
522
    /**
523 3
     * Adds a field to the list of fields to return. Also checks whether * is
524
     * set for the fields, if so it's removed from the field list.
525 3
     *
526 3
     * @deprecated Use getReturnFields()->add() instead, will be removed in 8.0
527
     * @param string $fieldName Name of a field to return in the result documents
528
     */
529
    public function addReturnField($fieldName)
530
    {
531 1
        GeneralUtility::logDeprecatedFunction();
532
        $this->returnFields->add($fieldName);
533 1
    }
534
535
    /**
536
     * Removes a field from the list of fields to return (fl parameter).
537
     *
538
     * @deprecated Use getReturnFields()->remove() instead, will be removed in 8.0
539 4
     * @param string $fieldName Field to remove from the list of fields to return
540
     */
541 4
    public function removeReturnField($fieldName)
542 4
    {
543 4
        GeneralUtility::logDeprecatedFunction();
544 2
        $this->returnFields->remove($fieldName);
545 4
    }
546
547
    // grouping
548 1
549 1
    /**
550 1
     * Activates and deactivates grouping for the current query.
551
     *
552 4
     * @param bool|Grouping $grouping TRUE to enable grouping, FALSE to disable grouping
553
     * @return void
554
     */
555
    public function setGrouping($grouping = true)
556
    {
557
        if ($grouping instanceof Grouping) {
558
            $this->grouping = $grouping;
559
            return;
560
        }
561
562 25
        /**
563
         * @deprecated
564 25
         * @todo When starting with 8.0 we can add a typehint Grouping to the grouping argument, to drop backwards compatibility.
565 25
         */
566 25
        $grouping = (bool)$grouping;
567
568 1
        if ($grouping) {
569
            GeneralUtility::deprecationLog('Usage of setGrouping with boolean deprecated please use getGrouping()->setIsEnabled()');
570
            $this->getGrouping()->setIsEnabled($grouping);
571 25
        } else {
572 25
            $this->initializeGrouping();
573
        }
574
    }
575
576
    /**
577
     * @return Grouping
578
     */
579 6
    public function getGrouping()
580
    {
581 6
        return $this->grouping;
582
    }
583 6
584 2
    /**
585
     * Sets the number of groups to return per group field or group query
586 6
     *
587
     * Internally uses the rows parameter.
588
     *
589
     * @deprecated Use getGrouping()->setNumberOfGroups() instead, will be removed in 8.0
590
     * @param int $numberOfGroups Number of groups per group.field or group.query
591
     */
592
    public function setNumberOfGroups($numberOfGroups)
593
    {
594 2
        GeneralUtility::logDeprecatedFunction();
595
        $this->getGrouping()->setNumberOfGroups($numberOfGroups);
596 2
    }
597 1
598 1
    /**
599 1
     * Gets the number of groups to return per group field or group query
600
     *
601 1
     * Internally uses the rows parameter.
602
     *
603 1
     * @deprecated Use getGrouping()->getNumberOfGroups() instead, will be removed in 8.0
604 1
     * @return int Number of groups per group.field or group.query
605
     */
606
    public function getNumberOfGroups()
607
    {
608 2
        GeneralUtility::logDeprecatedFunction();
609
        return $this->getGrouping()->getNumberOfGroups();
610
    }
611
612
    /**
613
     * Returns the number of results that should be shown per page
614
     *
615
     * @return int number of results to show per page
616
     */
617 1
    public function getResultsPerPage()
618
    {
619 1
        if ($this->getGrouping() instanceof Grouping && $this->getGrouping()->getIsEnabled()) {
620 1
            return $this->getGrouping()->getNumberOfGroups();
621
        }
622
623
        return $this->resultsPerPage;
624
    }
625
626
    /**
627
     * Sets the number of results that should be shown per page
628
     *
629 1
     * @param int $resultsPerPage Number of results to show per page
630
     * @return void
631 1
     */
632
    public function setResultsPerPage($resultsPerPage)
633
    {
634
        $this->resultsPerPage = max(intval($resultsPerPage), 0);
635
    }
636
637
    /**
638
     * Adds a field that should be used for grouping.
639 27
     *
640
     * @deprecated Use getGrouping()->addField() instead, will be removed in 8.0
641 27
     * @param string $fieldName Name of a field for grouping
642
     */
643
    public function addGroupField($fieldName)
644
    {
645
        GeneralUtility::logDeprecatedFunction();
646
        $this->getGrouping()->addField($fieldName);
647
    }
648
649
    /**
650 34
     * Gets the fields set for grouping.
651
     *
652 34
     * @deprecated Use getGrouping()->getFields() instead, will be removed in 8.0
653 34
     * @return array An array of fields set for grouping.
654
     */
655
    public function getGroupFields()
656
    {
657
        GeneralUtility::logDeprecatedFunction();
658
        return $this->getGrouping()->getFields();
659
    }
660 1
661
    /**
662 1
     * Adds sorting configuration for grouping.
663 1
     *
664
     * @deprecated Use getGrouping()->addSorting() instead, will be removed in 8.0
665
     * @param string $sorting value of sorting configuration
666 1
     * @param string $sorting value of sorting configuration
667 1
     */
668
    public function addGroupSorting($sorting)
669
    {
670
        GeneralUtility::logDeprecatedFunction();
671
        $this->getGrouping()->addSorting($sorting);
672
    }
673
674 1
    /**
675
     * Gets the sorting set for grouping.
676 1
     *
677
     * @deprecated Use getGrouping()->getSortings() instead, will be removed in 8.0
678
     * @return array An array of sorting configurations for grouping.
679
     */
680
    public function getGroupSortings()
681
    {
682
        GeneralUtility::logDeprecatedFunction();
683
        return $this->getGrouping()->getSortings();
684 1
    }
685
686 1
    // faceting
687 1
688
    /**
689 1
     * Adds a query that should be used for grouping.
690 1
     *
691
     * @deprecated Use getGrouping()->addQuery() instead, will be removed in 8.0
692
     * @param string $query Lucene query for grouping
693
     */
694
    public function addGroupQuery($query)
695
    {
696
        GeneralUtility::logDeprecatedFunction();
697 1
        $this->getGrouping()->addQuery($query);
698
    }
699 1
700
    /**
701
     * Gets the queries set for grouping.
702
     *
703
     * @deprecated Use getGrouping()->getQueries() instead, will be removed in 8.0
704
     * @return array An array of queries set for grouping.
705
     */
706
    public function getGroupQueries()
707
    {
708
        GeneralUtility::logDeprecatedFunction();
709 1
        return $this->getGrouping()->getQueries();
710
    }
711 1
712 1
    /**
713
     * Sets the maximum number of results to be returned per group.
714
     *
715 1
     * @deprecated Use getGrouping()->setResultsPerGroup() instead, will be removed in 8.0
716 1
     * @param int $numberOfResults Maximum number of results per group to return
717
     */
718
    public function setNumberOfResultsPerGroup($numberOfResults)
719
    {
720
        GeneralUtility::logDeprecatedFunction();
721
        $this->getGrouping()->setResultsPerGroup($numberOfResults);
722
    }
723 1
724
725 1
    /**
726
     * Gets the maximum number of results to be returned per group.
727
     *
728
     * @deprecated Use getGrouping()->getResultsPerGroup() instead, will be removed in 8.0
729
     * @return int Maximum number of results per group to return
730
     */
731
    public function getNumberOfResultsPerGroup()
732
    {
733 1
        GeneralUtility::logDeprecatedFunction();
734
        return $this->getGrouping()->getResultsPerGroup();
735 1
    }
736
737 1
    /**
738 1
     * Activates and deactivates faceting for the current query.
739
     *
740
     * @param bool|Faceting $faceting TRUE to enable faceting, FALSE to disable faceting
741
     * @return void
742
     */
743
    public function setFaceting($faceting = true)
744
    {
745
        if ($faceting instanceof Faceting) {
746
            $this->faceting = $faceting;
747 1
            return;
748
        }
749
750 1
        /**
751
         * @deprecated
752 1
         * @todo When starting with 8.0 we can add a typehint Faceting to the faceting argument, to drop backwards compatibility.
753 1
         */
754
        $faceting = (bool)$faceting;
755
756 1
        if ($faceting) {
757
            GeneralUtility::deprecationLog('Usage of setFaceting with boolean deprecated please use getFaceting()->setIsEnabled()');
758
            $this->getFaceting()->setIsEnabled($faceting);
759
        } else {
760
            $this->initializeFaceting();
761
        }
762
    }
763
764
    /**
765 33
     * @return Faceting
766
     */
767 33
    public function getFaceting()
768 33
    {
769 33
        return $this->faceting;
770 33
    }
771
772 33
    /**
773
     * Sets facet fields for a query.
774 1
     *
775
     * @deprecated Use getFaceting()->setFields() instead, will be removed in 8.0
776 33
     * @param array $facetFields Array of field names
777
     */
778
    public function setFacetFields(array $facetFields)
779
    {
780
        GeneralUtility::logDeprecatedFunction();
781
        $this->getFaceting()->setIsEnabled(true);
782
        $this->getFaceting()->setFields($facetFields);
783 1
    }
784
785 1
    /**
786
     * Adds a single facet field.
787 1
     *
788 1
     * @deprecated Use getFaceting()->addField() instead, will be removed in 8.0
789
     * @param string $facetField field name
790
     */
791
    public function addFacetField($facetField)
792 1
    {
793 1
        GeneralUtility::logDeprecatedFunction();
794
        $this->getFaceting()->setIsEnabled(true);
795
        $this->getFaceting()->addField($facetField);
796 1
    }
797
798
    /**
799
     * Removes a filter on a field
800
     *
801
     * @deprecated Use getFilters()->removeByFieldName() instead, will be removed in 8.0
802
     * @param string $filterFieldName The field name the filter should be removed for
803 33
     * @return void
804
     */
805 33
    public function removeFilter($filterFieldName)
806 33
    {
807
        GeneralUtility::logDeprecatedFunction();
808 10
        $this->getFilters()->removeByFieldName($filterFieldName);
809
    }
810
811
    /**
812 23
     * Removes a filter based on key of filter array
813 1
     *
814
     * @deprecated Use getFilters()->removeByName() instead, will be removed in 8.0
815
     * @param string $key array key
816 23
     */
817 23
    public function removeFilterByKey($key)
818
    {
819
        GeneralUtility::logDeprecatedFunction();
820
        $this->getFilters()->removeByName($key);
821
    }
822
823
    /**
824 1
     * Removes a filter by the filter value. The value has the following format:
825
     *
826 1
     * "fieldname:value"
827
     *
828 1
     * @deprecated Use getFilters()->removeByValue() instead, will be removed in 8.0
829 1
     * @param string $filterString The filter to remove, in the form of field:value
830
     */
831 1
    public function removeFilterByValue($filterString)
832
    {
833
        GeneralUtility::logDeprecatedFunction();
834
        $this->getFilters()->removeByValue($filterString);
835
    }
836
837
    /**
838 2
     * Gets all currently applied filters.
839
     *
840 2
     * @return Filters Array of filters
841 2
     */
842
    public function getFilters()
843
    {
844
        return $this->filters;
845
    }
846
847
    /**
848
     * Sets the filters to use.
849 1
     *
850
     * @param Filters $filters
851 1
     */
852 1
    public function setFilters(Filters $filters)
853 1
    {
854
        $this->filters = $filters;
855 1
    }
856
857
    // sorting
858 1
859
    /**
860
     * Sets access restrictions for a frontend user.
861
     *
862
     * @param array $groups Array of groups a user has been assigned to
863
     */
864
    public function setUserAccessGroups(array $groups)
865 1
    {
866
        $groups = array_map('intval', $groups);
867 1
        $groups[] = 0; // always grant access to public documents
868 1
        $groups = array_unique($groups);
869
        sort($groups, SORT_NUMERIC);
870
871
        $accessFilter = '{!typo3access}' . implode(',', $groups);
872
        $this->getFilters()->removeByPrefix('{!typo3access}');
873
        $this->getFilters()->add($accessFilter);
874
    }
875
876
    /**
877 1
     * Adds a filter parameter.
878
     *
879 1
     * @deprecated Use getFilters()->add() instead, will be removed in 8.0
880 1
     * @param string $filterString The filter to add, in the form of field:value
881
     * @return void
882
     */
883
    public function addFilter($filterString)
884 1
    {
885 1
        GeneralUtility::logDeprecatedFunction();
886
887
        $this->getFilters()->add($filterString);
888
    }
889
890
891
    // query parameters
892 12
893
    /**
894 12
     * Limits the query to certain sites
895
     *
896
     * @param string $allowedSites Comma-separated list of domains
897
     */
898
    public function setSiteHashFilter($allowedSites)
899
    {
900
        if (trim($allowedSites) === '*') {
901
            return;
902
        }
903
904 31
        $allowedSites = GeneralUtility::trimExplode(',', $allowedSites);
905
        $filters = [];
906 31
907 31
        foreach ($allowedSites as $site) {
908 31
            $siteHash = $this->siteHashService->getSiteHashForDomain($site);
909 31
            $filters[] = 'siteHash:"' . $siteHash . '"';
910
        }
911 31
912
        $this->getFilters()->add(implode(' OR ', $filters));
913 31
    }
914 27
915 27
    /**
916
     * Limits the query to certain page tree branches
917
     *
918
     * @param string $pageIds Comma-separated list of page IDs
919 31
     */
920 31
    public function setRootlineFilter($pageIds)
921
    {
922
        $pageIds = GeneralUtility::trimExplode(',', $pageIds);
923
        $filters = [];
924
925
            /** @var $processor PageUidToHierarchy */
926
        $processor = GeneralUtility::makeInstance(PageUidToHierarchy::class);
927
        $hierarchies = $processor->process($pageIds);
928 39
929
        foreach ($hierarchies as $hierarchy) {
930
            $lastLevel = array_pop($hierarchy);
931 39
            $filters[] = 'rootline:"' . $lastLevel . '"';
932
        }
933
934
        $this->getFilters()->add(implode(' OR ', $filters));
935
    }
936
937
    /**
938
     * Gets the list of fields a query will return.
939
     *
940
     * @deprecated Use method getReturnFields() instead, will be removed in 8.0
941 39
     * @return array List of field names the query will return
942 39
     */
943
    public function getFieldList()
944
    {
945
        GeneralUtility::logDeprecatedFunction();
946
        return $this->getReturnFields()->getValues();
947
    }
948
949
    /**
950
     * Sets the fields to return by a query.
951
     *
952 28
     * @deprecated Use method setReturnFields() instead, will be removed in 8.0
953
     * @param array|string $fieldList an array or comma-separated list of field names
954 28
     * @throws \UnexpectedValueException on parameters other than comma-separated lists and arrays
955 1
     */
956
    public function setFieldList($fieldList = ['*', 'score'])
957
    {
958 27
        GeneralUtility::logDeprecatedFunction();
959 27
        if ($fieldList === null) {
960
            $this->setReturnFields(ReturnFields::fromArray(['*', 'score']));
961 27
            return;
962 27
        }
963 27
964
965
        if (is_string($fieldList)) {
966 27
            $this->setReturnFields(ReturnFields::fromString($fieldList));
967 27
            return;
968
        }
969
970
        if (is_array($fieldList)) {
971
            $this->setReturnFields(ReturnFields::fromArray($fieldList));
972
            return;
973
        }
974
975
        throw new \UnexpectedValueException('Field list must be a FieldList object.', 1310740308);
976
    }
977
978
    /**
979
     * @param ReturnFields $returnFields
980
     */
981
    public function setReturnFields(ReturnFields $returnFields)
982
    {
983
        $this->returnFields = $returnFields;
984
    }
985
986
    /**
987
     * @return ReturnFields
988
     */
989
    public function getReturnFields()
990
    {
991
        return $this->returnFields;
992
    }
993
994
    /**
995
     * Gets the query type, Solr's qt parameter.
996 6
     *
997
     * @return string Query type, qt parameter.
998 6
     */
999
    public function getQueryType()
1000
    {
1001
        return $this->queryParameters['qt'];
1002
    }
1003
1004
    /**
1005
     * Sets the query type, Solr's qt parameter.
1006
     *
1007 3
     * @param string|bool $queryType String query type or boolean FALSE to disable / reset the qt parameter.
1008
     * @see http://wiki.apache.org/solr/CoreQueryParameters#qt
1009 3
     */
1010 2
    public function setQueryType($queryType)
1011
    {
1012
        $this->setQueryParameterWhenStringOrUnsetWhenEmpty('qt', $queryType);
1013 3
    }
1014 1
1015 1
    /**
1016 1
     * Sets the query operator to AND or OR. Unsets the query operator (actually
1017
     * sets it back to default) for FALSE.
1018
     *
1019
     * @param string|bool $operator AND or OR, FALSE to unset
1020 3
     */
1021 3
    public function setOperator($operator)
1022
    {
1023
        if (in_array($operator, [self::OPERATOR_AND, self::OPERATOR_OR])) {
1024
            $this->queryParameters['q.op'] = $operator;
1025
        }
1026
1027
        if ($operator === false) {
1028 1
            unset($this->queryParameters['q.op']);
1029
        }
1030 1
    }
1031
1032
    /**
1033
     * Gets the alternative query, Solr's q.alt parameter.
1034
     *
1035
     * @return string Alternative query, q.alt parameter.
1036
     */
1037
    public function getAlternativeQuery()
1038
    {
1039 2
        return $this->queryParameters['q.alt'];
1040
    }
1041 2
1042 2
    /**
1043
     * Sets an alternative query, Solr's q.alt parameter.
1044 1
     *
1045
     * This query supports the complete Lucene Query Language.
1046 2
     *
1047
     * @param mixed $alternativeQuery String alternative query or boolean FALSE to disable / reset the q.alt parameter.
1048
     * @see http://wiki.apache.org/solr/DisMaxQParserPlugin#q.alt
1049
     */
1050
    public function setAlternativeQuery($alternativeQuery)
1051
    {
1052
        $this->setQueryParameterWhenStringOrUnsetWhenEmpty('q.alt', $alternativeQuery);
1053
    }
1054 1
1055
    // keywords
1056 1
1057 1
    /**
1058
     * Set the query to omit the response header
1059
     *
1060 1
     * @param bool $omitHeader TRUE (default) to omit response headers, FALSE to re-enable
1061 1
     */
1062
    public function setOmitHeader($omitHeader = true)
1063 1
    {
1064
        $omitHeader = ($omitHeader === true) ? 'true' : $omitHeader;
1065
        $this->setQueryParameterWhenStringOrUnsetWhenEmpty('omitHeader', $omitHeader);
1066
    }
1067
1068
    /**
1069
     * Get the query keywords, keywords are escaped.
1070 1
     *
1071
     * @return string query keywords
1072 1
     */
1073
    public function getKeywords()
1074
    {
1075
        return $this->keywords;
1076
    }
1077
1078
    /**
1079
     * Sets the query keywords, escapes them as needed for Solr/Lucene.
1080
     *
1081
     * @param string $keywords user search terms/keywords
1082
     */
1083 28
    public function setKeywords($keywords)
1084
    {
1085 28
        $this->keywords = $this->escapeService->escape($keywords);
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->escapeService->escape($keywords) can also be of type integer or double. However, the property $keywords is declared as type string. Maybe add an additional type check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.

For example, imagine you have a variable $accountId that can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to the id property of an instance of the Account class. This class holds a proper account, so the id value must no longer be false.

Either this assignment is in error or a type check should be added for that assignment.

class Id
{
    public $id;

    public function __construct($id)
    {
        $this->id = $id;
    }

}

class Account
{
    /** @var  Id $id */
    public $id;
}

$account_id = false;

if (starsAreRight()) {
    $account_id = new Id(42);
}

$account = new Account();
if ($account instanceof Id)
{
    $account->id = $account_id;
}
Loading history...
1086 28
        $this->keywordsRaw = $keywords;
1087
    }
1088 1
1089
    /**
1090 28
     * Gets the cleaned keywords so that it can be used in templates f.e.
1091
     *
1092
     * @return string The cleaned keywords.
1093
     */
1094
    public function getKeywordsCleaned()
1095
    {
1096
        return $this->cleanKeywords($this->keywordsRaw);
1097
    }
1098
1099 1
    /**
1100
     * Helper method to escape/encode keywords for use in HTML
1101 1
     *
1102 1
     * @param string $keywords Keywords to prepare for use in HTML
1103
     * @return string Encoded keywords
1104 1
     */
1105
    public static function cleanKeywords($keywords)
1106 1
    {
1107
        $keywords = trim($keywords);
1108
        $keywords = GeneralUtility::removeXSS($keywords);
1109
        $keywords = htmlentities($keywords, ENT_QUOTES, $GLOBALS['TSFE']->metaCharset);
1110
        return $keywords;
1111
    }
1112
1113 22
    /**
1114
     * Escapes marker hashes and the pipe symbol so that they will not be
1115 22
     * executed in templates.
1116
     *
1117
     * @param string $content Content potentially containing markers
1118
     * @deprecated Only needed for old templating. Will be removed in 8.0
1119
     * @return string Content with markers escaped
1120
     */
1121
    protected static function escapeMarkers($content)
1122
    {
1123 125
        GeneralUtility::logDeprecatedFunction();
1124
1125 125
        // escape marker hashes
1126 125
        $content = str_replace('###', '&#35;&#35;&#35;', $content);
1127 125
        // escape pipe character used for parameter separation
1128
        $content = str_replace('|', '&#124;', $content);
1129
1130
        return $content;
1131
    }
1132
1133
    // relevance, matching
1134 22
1135
    /**
1136 22
     * Gets the raw, unescaped, unencoded keywords.
1137
     *
1138
     * USE WITH CAUTION!
1139
     *
1140
     * @return string raw keywords
1141
     */
1142
    public function getKeywordsRaw()
1143
    {
1144
        return $this->keywordsRaw;
1145 22
    }
1146
1147 22
    /**
1148 22
     * Sets the minimum match (mm) parameter
1149 22
     *
1150 22
     * @param mixed $minimumMatch Minimum match parameter as string or boolean FALSE to disable / reset the mm parameter
1151
     * @see http://wiki.apache.org/solr/DisMaxRequestHandler#mm_.28Minimum_.27Should.27_Match.29
1152
     */
1153
    public function setMinimumMatch($minimumMatch)
1154 22
    {
1155
        $this->setQueryParameterWhenStringOrUnsetWhenEmpty('mm', $minimumMatch);
1156 22
    }
1157
1158
    /**
1159
     * Sets the boost function (bf) parameter
1160
     *
1161
     * @param mixed $boostFunction boost function parameter as string or boolean FALSE to disable / reset the bf parameter
1162
     * @see http://wiki.apache.org/solr/DisMaxRequestHandler#bf_.28Boost_Functions.29
1163
     */
1164
    public function setBoostFunction($boostFunction)
1165
    {
1166 22
        $this->setQueryParameterWhenStringOrUnsetWhenEmpty('bf', $boostFunction);
1167
    }
1168
1169 22
    // query fields
1170
    // TODO move up to field list methods
1171 22
1172
    /**
1173 22
     * Sets the boost query (bq) parameter
1174
     *
1175
     * @param mixed $boostQuery boost query parameter as string or array to set a boost query or boolean FALSE to disable / reset the bq parameter
1176
     * @see http://wiki.apache.org/solr/DisMaxQParserPlugin#bq_.28Boost_Query.29
1177
     */
1178
    public function setBoostQuery($boostQuery)
1179
    {
1180
        if (is_array($boostQuery)) {
1181
            $this->queryParameters['bq'] = $boostQuery;
1182
            return;
1183
        }
1184
        $this->setQueryParameterWhenStringOrUnsetWhenEmpty('bq', $boostQuery);
1185
    }
1186
1187
    /**
1188
     * Gets a specific query parameter by its name.
1189
     *
1190
     * @param string $parameterName The parameter to return
1191
     * @param mixed $defaultIfEmpty
1192
     * @return mixed The parameter's value or $defaultIfEmpty if not set
1193
     */
1194
    public function getQueryParameter($parameterName, $defaultIfEmpty = null)
1195
    {
1196 1
        $parameters = $this->getQueryParameters();
1197
        return isset($parameters[$parameterName]) ? $parameters[$parameterName] : $defaultIfEmpty;
1198 1
    }
1199 1
1200
    /**
1201 1
     * Builds an array of query parameters to use for the search query.
1202
     *
1203 1
     * @return array An array ready to use with query parameters
1204
     */
1205
    public function getQueryParameters()
1206
    {
1207
        $queryParameters = $this->getReturnFields()->build();
1208
        $queryParameters = array_merge($queryParameters, $this->getFilters()->build());
1209
        $queryParameters = array_merge($queryParameters, $this->queryParameters);
1210
        $queryParameters = array_merge($queryParameters, $this->getQueryFields()->build());
1211 1
        $queryParameters = array_merge($queryParameters, $this->getHighlighting()->build());
1212
        $queryParameters = array_merge($queryParameters, $this->getFaceting()->build());
1213 1
        $queryParameters = array_merge($queryParameters, $this->getGrouping()->build());
1214 1
1215
        return $queryParameters;
1216 1
    }
1217
1218 1
    // general query parameters
1219
1220
    /**
1221
     * Compiles the query fields into a string to be used in Solr's qf parameter.
1222
     *
1223
     * @deprecated Use getQueryFields()->toString() please. Will be removed in 8.0
1224
     * @return string A string of query fields with their associated boosts
1225
     */
1226
    public function getQueryFieldsAsString()
1227
    {
1228
        GeneralUtility::logDeprecatedFunction();
1229 1
        return $this->getQueryFields()->toString();
1230
    }
1231 1
1232 1
    /**
1233
     * Enables or disables highlighting of search terms in result teasers.
1234 1
     *
1235
     * @param Highlighting|bool $highlighting Enables highlighting when set to TRUE, deactivates highlighting when set to FALSE, defaults to TRUE.
1236 1
     * @param int $fragmentSize Size, in characters, of fragments to consider for highlighting.
1237
     * @see http://wiki.apache.org/solr/HighlightingParameters
1238
     * @return void
1239
     */
1240
    public function setHighlighting($highlighting = true, $fragmentSize = 200)
1241
    {
1242
        if ($highlighting instanceof Highlighting) {
1243
            $this->highlighting = $highlighting;
1244
            return;
1245 10
        }
1246
1247 10
        /**
1248 10
         * @deprecated
1249
         * @todo When starting with 8.0 we can add a typehint Highlighting to the highlighting argument and remove fragmentsize, to drop backwards compatibility.
1250
         */
1251
        GeneralUtility::deprecationLog('Usage of setHighlighting with boolean or fragmentSize is deprecated please use getHighlighting()->setIsEnabled() or getHighlighting()->setFragmentSize() please');
1252
        $highlighting = (bool)$highlighting;
1253
        $this->getHighlighting()->setIsEnabled($highlighting);
1254
        $this->getHighlighting()->setFragmentSize($fragmentSize);
1255
    }
1256 67
1257
    /**
1258 67
     * @return Highlighting
1259
     */
1260 67
    public function getHighlighting()
1261 67
    {
1262
        return $this->highlighting;
1263 67
    }
1264
1265
    // misc
1266 67
1267 67
    /**
1268 30
     * Enables or disables spellchecking for the query.
1269
     *
1270
     * @param bool $spellchecking Enables spellchecking when set to TRUE, deactivates spellchecking when set to FALSE, defaults to TRUE.
1271 67
     */
1272
    public function setSpellchecking($spellchecking = true)
1273
    {
1274
        if ($spellchecking) {
1275
            $this->queryParameters['spellcheck'] = 'true';
1276
            $this->queryParameters['spellcheck.collate'] = 'true';
1277
            $maxCollationTries = $this->solrConfiguration->getSearchSpellcheckingNumberOfSuggestionsToTry();
1278
            $this->addQueryParameter('spellcheck.maxCollationTries', $maxCollationTries);
1279
        } else {
1280
            unset($this->queryParameters['spellcheck']);
1281 69
            unset($this->queryParameters['spellcheck.collate']);
1282
            unset($this->queryParameters['spellcheck.maxCollationTries']);
1283 69
        }
1284
    }
1285 69
1286 31
    /**
1287
     * This method can be used to set a query parameter when the value is a string and not empty or unset it
1288 31
     * in any other case. Extracted to avoid duplicate code.
1289 31
     *
1290
     * @param string $parameterName
1291
     * @param mixed $value
1292 31
     */
1293
    private function setQueryParameterWhenStringOrUnsetWhenEmpty($parameterName, $value)
1294
    {
1295 69
        if (is_string($value) && !empty($value)) {
1296
            $this->addQueryParameter($parameterName, $value);
1297
        } else {
1298
            unset($this->queryParameters[$parameterName]);
1299
        }
1300
    }
1301
1302
    /**
1303
     * Adds any generic query parameter.
1304
     *
1305
     * @param string $parameterName Query parameter name
1306 33
     * @param string $parameterValue Parameter value
1307
     */
1308 33
    public function addQueryParameter($parameterName, $parameterValue)
1309 33
    {
1310 33
        $this->queryParameters[$parameterName] = $parameterValue;
1311
    }
1312 33
1313 33
    /**
1314 27
     * Sets the sort parameter.
1315
     *
1316
     * $sorting must include a field name (or the pseudo-field score),
1317
     * followed by a space,
1318
     * followed by a sort direction (asc or desc).
1319 33
     *
1320 33
     * Multiple fallback sortings can be separated by comma,
1321
     * ie: <field name> <direction>[,<field name> <direction>]...
1322 33
     *
1323 31
     * @param string|bool $sorting Either a comma-separated list of sort fields and directions or FALSE to reset sorting to the default behavior (sort by score / relevance)
1324 31
     * @see http://wiki.apache.org/solr/CommonQueryParameters#sort
1325 31
     */
1326
    public function setSorting($sorting)
1327
    {
1328 33
        if ($sorting) {
1329 28
            if (!is_string($sorting)) {
1330 33
                throw new \InvalidArgumentException('Sorting needs to be a string!');
1331
            }
1332
            $sortParameter = $this->removeRelevanceSortField($sorting);
1333
            $this->queryParameters['sort'] = $sortParameter;
1334 1
        } else {
1335 1
            unset($this->queryParameters['sort']);
1336 1
        }
1337
    }
1338
1339
    /**
1340 33
     * Removes the relevance sort field if present in the sorting field definition.
1341
     *
1342
     * @param string $sorting
1343
     * @return string
1344
     */
1345
    protected function removeRelevanceSortField($sorting)
1346
    {
1347
        $sortParameter = $sorting;
1348
        list($sortField) = explode(' ', $sorting);
1349 24
        if ($sortField == 'relevance') {
1350
            $sortParameter = '';
1351 24
            return $sortParameter;
1352 24
        }
1353 24
1354 24
        return $sortParameter;
1355 24
    }
1356
1357 1
    /**
1358 1
     * Enables or disables the debug parameter for the query.
1359 1
     *
1360
     * @param bool $debugMode Enables debugging when set to TRUE, deactivates debugging when set to FALSE, defaults to TRUE.
1361 24
     */
1362
    public function setDebugMode($debugMode = true)
1363
    {
1364
        if ($debugMode) {
1365
            $this->queryParameters['debugQuery'] = 'true';
1366
            $this->queryParameters['echoParams'] = 'all';
1367
        } else {
1368
            unset($this->queryParameters['debugQuery']);
1369 32
            unset($this->queryParameters['echoParams']);
1370
        }
1371 32
    }
1372 32
1373
    /**
1374
     * Returns the link target page id.
1375
     *
1376
     * @return int
1377
     */
1378
    public function getLinkTargetPageId()
1379
    {
1380
        return $this->linkTargetPageId;
1381
    }
1382
1383
    /**
1384
     * Activates the collapsing on the configured field, if collapsing was enabled.
1385
     *
1386
     * @return bool
1387 2
     */
1388
    protected function initializeCollapsingFromConfiguration()
1389 2
    {
1390 2
        // check collapsing
1391
        if ($this->solrConfiguration->getSearchVariants()) {
1392
            $collapseField = $this->solrConfiguration->getSearchVariantsField();
1393 2
            $this->setVariantField($collapseField);
1394 2
            $this->setCollapsing(true);
1395
1396 1
            return true;
1397
        }
1398 2
1399
        return false;
1400
    }
1401
1402
    /**
1403
     * @return void
1404
     */
1405
    protected function initializeFaceting()
1406 2
    {
1407
        $faceting = Faceting::fromTypoScriptConfiguration($this->solrConfiguration);
1408 2
        $this->setFaceting($faceting);
1409 2
    }
1410 2
1411 1
    /**
1412 1
     * @return void
1413
     */
1414
    protected function initializeGrouping()
1415 2
    {
1416
        $grouping = Grouping::fromTypoScriptConfiguration($this->solrConfiguration);
1417
        $this->setGrouping($grouping);
1418
    }
1419
1420
    /**
1421
     * @return void
1422
     */
1423 22
    protected function initializeFilters()
1424
    {
1425 22
        $filters = Filters::fromTypoScriptConfiguration($this->solrConfiguration);
1426 22
        $this->setFilters($filters);
1427 22
    }
1428
}
1429