Completed
Push — master ( 6ee2a7...5f60a5 )
by Rafael
04:29
created

Query::__construct()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 24
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 24
rs 8.9713
c 0
b 0
f 0
cc 1
eloc 20
nc 1
nop 1
1
<?php
2
namespace ApacheSolrForTypo3\Solr\Domain\Search\Query;
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 3 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\Pagination;
28
use ApacheSolrForTypo3\Solr\Domain\Search\Query\Helper\QueryStringContainer;
29
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\BigramPhraseFields;
30
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Debug;
31
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Elevation;
32
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Faceting;
33
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\FieldCollapsing;
34
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Filters;
35
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Grouping;
36
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Highlighting;
37
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Operator;
38
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\PhraseFields;
39
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\QueryFields;
40
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\ReturnFields;
41
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Slops;
42
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Sorting;
43
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\Spellchecking;
44
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\TrigramPhraseFields;
45
46
/**
47
 * A Solr search query
48
 *
49
 * @author Ingo Renner <[email protected]>
50
 * @author Timo Hund <[email protected]>
51
 */
52
class Query
53
{
54
    /**
55
     * @var QueryStringContainer
56
     */
57
    protected $queryStringContainer = null;
58
59
    /**
60
     * @var Pagination
61
     */
62
    protected $pagination = null;
63
64
    /**
65
     * @var Operator
66
     */
67
    protected $operator = null;
68
69
    /**
70
     * ParameterBuilder for filters.
71
     *
72
     * @var Filters
73
     */
74
    protected $filters = null;
75
76
    /**
77
     * Holds the query fields with their associated boosts. The key represents
78
     * the field name, value represents the field's boost. These are the fields
79
     * that will actually be searched.
80
     *
81
     * Used in Solr's qf parameter
82
     *
83
     * @var QueryFields
84
     * @see http://wiki.apache.org/solr/DisMaxQParserPlugin#qf_.28Query_Fields.29
85
     */
86
    protected $queryFields = null;
87
88
    /**
89
     * Holds the phrase fields with their associated boosts. The key represents
90
     * the field name, value represents the field's boost. These are the fields
91
     * for those Apache Solr should build phrase quieries and by phrase occurrences should be boosted.
92
     *
93
     * @var PhraseFields
94
     * @see https://lucene.apache.org/solr/guide/7_0/the-dismax-query-parser.html#pf-phrase-fields-parameter
95
     */
96
    protected $phraseFields;
97
98
    /**
99
     * Holds the bigram phrase fields with their associated boosts. The key represents
100
     * the field name, value represents the field's boost. These are the fields
101
     * for those Apache Solr should build the phrases from triplets and sentences.
102
     *
103
     * @var BigramPhraseFields
104
     * @see "pf2" https://lucene.apache.org/solr/guide/7_0/the-extended-dismax-query-parser.html#extended-dismax-parameters
105
     */
106
    protected $bigramPhraseFields;
107
108
    /**
109
     * Holds the trigram phrase fields with their associated boosts. The key represents
110
     * the field name, value represents the field's boost. These are the fields
111
     * for those Apache Solr should build the phrases from triplets and sentences.
112
     *
113
     * @var TrigramPhraseFields
114
     * @see "pf3" https://lucene.apache.org/solr/guide/7_0/the-extended-dismax-query-parser.html#extended-dismax-parameters
115
     */
116
    protected $trigramPhraseFields;
117
118
    /**
119
     * List of fields that will be returned in the result documents.
120
     *
121
     * used in Solr's fl parameter
122
     *
123
     * @var ReturnFields
124
     * @see http://wiki.apache.org/solr/CommonQueryParameters#fl
125
     */
126
    protected $returnFields = null;
127
128
    /**
129
     * ParameterBuilder for the highlighting.
130
     *
131
     * @var Highlighting
132
     */
133
    protected $highlighting = null;
134
135
    /**
136
     * ParameterBuilder for the faceting.
137
     *
138
     * @var Faceting
139
     */
140
    protected $faceting = null;
141
142
    /**
143
     * ParameterBuilder for the spellchecking
144
     *
145
     * @var Spellchecking
146
     */
147
    protected $spellchecking = null;
148
149
    /**
150
     * ParameterBuilder for the grouping.
151
     *
152
     * @var Grouping
153
     */
154
    protected $grouping = null;
155
156
    /**
157
     * ParameterBuilder for the field collapsing (variants)
158
     *
159
     * @var FieldCollapsing
160
     */
161
    protected $fieldCollapsing = null;
162
163
    /**
164
     * ParameterBuilder for the debugging.
165
     *
166
     * @var Debug
167
     */
168
    protected $debug = null;
169
170
    /**
171
     * ParameterBuilder for the sorting
172
     *
173
     * @var Sorting
174
     */
175
    protected $sorting = null;
176
177
    /**
178
     * ParameterBuilder for the slops (qs,ps,ps2,ps3)
179
     *
180
     * @var Slops
181
     */
182
    protected $slops = null;
183
184
    /**
185
     * ParameterBuilder for the elevation
186
     *
187
     * @var Elevation
188
     */
189
    protected $elevation = null;
190
191
    /**
192
     * @var QueryParametersContainer
193
     */
194
    protected $queryParametersContainer = null;
195
196
    /**
197
     * Query constructor.
198
     * @param string $keywords
199
     */
200
    public function __construct($keywords)
201
    {
202
        $this->queryStringContainer = new QueryStringContainer((string)$keywords);
203
        $this->pagination = new Pagination();
204
        $this->filters = new Filters();
205
        $this->queryFields = QueryFields::fromString('*');
206
        $this->returnFields = ReturnFields::fromArray(['*', 'score']);
207
208
        $this->faceting = new Faceting(false);
209
        $this->grouping = new Grouping(false);
210
        $this->highlighting = new Highlighting(false);
211
        $this->bigramPhraseFields = new BigramPhraseFields(false);
212
        $this->trigramPhraseFields = new TrigramPhraseFields(false);
213
        $this->phraseFields = new PhraseFields(false);
214
        $this->spellchecking = new Spellchecking(false);
215
        $this->debug = new Debug(false);
216
        $this->sorting = new Sorting(false);
217
        $this->fieldCollapsing = new FieldCollapsing(false);
218
        $this->elevation = new Elevation(false);
219
        $this->operator = new Operator(false);
220
        $this->slops = new Slops();
221
222
        $this->queryParametersContainer = new QueryParametersContainer();
223
    }
224
225
    /**
226
     * @param QueryFields $queryFields
227
     */
228
    public function setQueryFields(QueryFields $queryFields)
229
    {
230
        $this->queryFields = $queryFields;
231
    }
232
233
    /**
234
     * @return QueryFields
235
     */
236
    public function getQueryFields()
237
    {
238
        return $this->queryFields;
239
    }
240
241
    /**
242
     * @param PhraseFields $phraseFields
243
     * @return void
244
     */
245
    public function setPhraseFields(PhraseFields $phraseFields)
246
    {
247
        $this->phraseFields = $phraseFields;
248
    }
249
250
    /**
251
     * @return PhraseFields
252
     */
253
    public function getPhraseFields()
254
    {
255
        return $this->phraseFields;
256
    }
257
258
    /**
259
     * @return BigramPhraseFields
260
     */
261
    public function getBigramPhraseFields()
262
    {
263
        return $this->bigramPhraseFields;
264
    }
265
266
    /**
267
     * @param BigramPhraseFields $bigramPhraseFields
268
     * @return void
269
     */
270
    public function setBigramPhraseFields(BigramPhraseFields $bigramPhraseFields)
271
    {
272
        $this->bigramPhraseFields = $bigramPhraseFields;
273
    }
274
275
    /**
276
     * @return TrigramPhraseFields
277
     */
278
    public function getTrigramPhraseFields()
279
    {
280
        return $this->trigramPhraseFields;
281
    }
282
283
    /**
284
     * @param TrigramPhraseFields $trigramPhraseFields
285
     * @return void
286
     */
287
    public function setTrigramPhraseFields(TrigramPhraseFields $trigramPhraseFields)
288
    {
289
        $this->trigramPhraseFields = $trigramPhraseFields;
290
    }
291
292
    /**
293
     * returns a string representation of the query
294
     *
295
     * @return string the string representation of the query
296
     */
297
    public function __toString()
298
    {
299
        return $this->queryStringContainer->__toString();
300
    }
301
302
    /**
303
     * Builds the query string which is then used for Solr's q parameters
304
     *
305
     * @return QueryStringContainer
306
     */
307
    public function getQueryStringContainer()
308
    {
309
        return $this->queryStringContainer;
310
    }
311
312
    /**
313
     * @param QueryStringContainer $queryStringContainer
314
     */
315
    public function setQueryStringContainer(QueryStringContainer $queryStringContainer)
316
    {
317
        $this->queryStringContainer = $queryStringContainer;
318
    }
319
320
    /**
321
     * @return Pagination
322
     */
323
    public function getPagination(): Pagination
324
    {
325
        return $this->pagination;
326
    }
327
328
    /**
329
     * @param Pagination $pagination
330
     */
331
    public function setPagination(Pagination $pagination)
332
    {
333
        $this->pagination = $pagination;
334
    }
335
336
    // query elevation
337
338
    /**
339
     * @param Elevation $elevation
340
     */
341
    public function setElevation(Elevation $elevation)
342
    {
343
        $this->elevation = $elevation;
344
    }
345
346
    /**
347
     * @return Elevation
348
     */
349
    public function getElevation(): Elevation
350
    {
351
        return $this->elevation;
352
    }
353
354
    // collapsing
355
356
    /**
357
     * @param FieldCollapsing $fieldCollapsing
358
     */
359
    public function setFieldCollapsing(FieldCollapsing $fieldCollapsing)
360
    {
361
        $this->fieldCollapsing = $fieldCollapsing;
362
    }
363
364
    /**
365
     * @return FieldCollapsing
366
     */
367
    public function getFieldCollapsing(): FieldCollapsing
368
    {
369
        return $this->fieldCollapsing;
370
    }
371
372
    // grouping
373
374
    /**
375
     * Activates and deactivates grouping for the current query.
376
     *
377
     * @param Grouping $grouping TRUE to enable grouping, FALSE to disable grouping
378
     * @return void
379
     */
380
    public function setGrouping(Grouping $grouping)
381
    {
382
        $this->grouping = $grouping;
383
    }
384
385
    /**
386
     * @return Grouping
387
     */
388
    public function getGrouping(): Grouping
389
    {
390
        return $this->grouping;
391
    }
392
393
    /**
394
     * Returns the number of results that should be shown per page or the number of groups, when grouping is active
395
     *
396
     * @return int number of results to show per page
397
     */
398
    public function getRows()
399
    {
400
        if ($this->getGrouping() instanceof Grouping && $this->getGrouping()->getIsEnabled()) {
401
            return $this->getGrouping()->getNumberOfGroups();
402
        }
403
404
        return $this->getPagination()->getResultsPerPage();
405
    }
406
407
    // faceting
408
409
    /**
410
     * Activates and deactivates faceting for the current query.
411
     *
412
     * @param Faceting $faceting TRUE to enable faceting, FALSE to disable faceting
413
     * @return void
414
     */
415
    public function setFaceting(Faceting $faceting)
416
    {
417
        $this->faceting = $faceting;
418
    }
419
420
    /**
421
     * @return Faceting
422
     */
423
    public function getFaceting(): Faceting
424
    {
425
        return $this->faceting;
426
    }
427
428
    /**
429
     * Sets the filters to use.
430
     *
431
     * @param Filters $filters
432
     */
433
    public function setFilters(Filters $filters)
434
    {
435
        $this->filters = $filters;
436
    }
437
438
    /**
439
     * Gets all currently applied filters.
440
     *
441
     * @return Filters Array of filters
442
     */
443
    public function getFilters(): Filters
444
    {
445
        return $this->filters;
446
    }
447
448
    /**
449
     * @param ReturnFields $returnFields
450
     */
451
    public function setReturnFields(ReturnFields $returnFields)
452
    {
453
        $this->returnFields = $returnFields;
454
    }
455
456
    /**
457
     * @return ReturnFields
458
     */
459
    public function getReturnFields(): ReturnFields
460
    {
461
        return $this->returnFields;
462
    }
463
464
    /**
465
     * Gets the query type, Solr's qt parameter.
466
     *
467
     * @return string Query type, qt parameter.
468
     */
469
    public function getQueryType()
470
    {
471
        return $this->queryParametersContainer->get('qt');
472
    }
473
474
    /**
475
     * Sets the query type, Solr's qt parameter.
476
     *
477
     * @param string|bool $queryType String query type or boolean FALSE to disable / reset the qt parameter.
478
     * @see http://wiki.apache.org/solr/CoreQueryParameters#qt
479
     */
480
    public function setQueryType($queryType)
481
    {
482
        $this->queryParametersContainer->setWhenStringOrUnsetWhenEmpty('qt', $queryType);
483
    }
484
485
    /**
486
     * Set the operator that should be used for the query. Operators an be created e.g. by using
487
     * Operator::and()
488
     *
489
     * @param Operator $operator
490
     */
491
    public function setOperator(Operator $operator)
492
    {
493
        $this->operator = $operator;
494
    }
495
496
    /**
497
     * Returns the operator of the query.
498
     *
499
     * @return Operator
500
     */
501
    public function getOperator(): Operator
502
    {
503
        return $this->operator;
504
    }
505
506
    /**
507
     * @return Slops
508
     */
509
    public function getSlops(): Slops
510
    {
511
        return $this->slops;
512
    }
513
514
    /**
515
     * @param Slops $slops
516
     */
517
    public function setSlops(Slops $slops)
518
    {
519
        $this->slops = $slops;
520
    }
521
522
    /**
523
     * Gets the alternative query, Solr's q.alt parameter.
524
     *
525
     * @return string Alternative query, q.alt parameter.
526
     */
527
    public function getAlternativeQuery()
528
    {
529
        return $this->queryParametersContainer->get('q.alt');
530
    }
531
532
    /**
533
     * Sets an alternative query, Solr's q.alt parameter.
534
     *
535
     * This query supports the complete Lucene Query Language.
536
     *
537
     * @param string $alternativeQuery String alternative query or boolean FALSE to disable / reset the q.alt parameter.
538
     * @see http://wiki.apache.org/solr/DisMaxQParserPlugin#q.alt
539
     */
540
    public function setAlternativeQuery($alternativeQuery)
541
    {
542
        $this->queryParametersContainer->setWhenStringOrUnsetWhenEmpty('q.alt', $alternativeQuery);
543
    }
544
545
    // keywords
546
547
    /**
548
     * Set the query to omit the response header
549
     *
550
     * @param bool $omitHeader TRUE (default) to omit response headers, FALSE to re-enable
551
     */
552
    public function setOmitHeader($omitHeader = true)
553
    {
554
        $omitHeader = ($omitHeader === true) ? 'true' : $omitHeader;
555
        $this->queryParametersContainer->setWhenStringOrUnsetWhenEmpty('omitHeader', $omitHeader);
556
    }
557
558
    /**
559
     * Sets the minimum match (mm) parameter
560
     *
561
     * @param mixed $minimumMatch Minimum match parameter as string or boolean FALSE to disable / reset the mm parameter
562
     * @see http://wiki.apache.org/solr/DisMaxRequestHandler#mm_.28Minimum_.27Should.27_Match.29
563
     */
564
    public function setMinimumMatch($minimumMatch)
565
    {
566
        $this->queryParametersContainer->setWhenStringOrUnsetWhenEmpty('mm', $minimumMatch);
567
    }
568
569
    /**
570
     * Sets the boost function (bf) parameter
571
     *
572
     * @param mixed $boostFunction boost function parameter as string or boolean FALSE to disable / reset the bf parameter
573
     * @see http://wiki.apache.org/solr/DisMaxRequestHandler#bf_.28Boost_Functions.29
574
     */
575
    public function setBoostFunction($boostFunction)
576
    {
577
        $this->queryParametersContainer->setWhenStringOrUnsetWhenEmpty('bf', $boostFunction);
578
    }
579
580
    /**
581
     * Sets the boost query (bq) parameter
582
     *
583
     * @param mixed $boostQuery boost query parameter as string or array to set a boost query or boolean FALSE to disable / reset the bq parameter
584
     * @see http://wiki.apache.org/solr/DisMaxQParserPlugin#bq_.28Boost_Query.29
585
     */
586
    public function setBoostQuery($boostQuery)
587
    {
588
        if (is_array($boostQuery)) {
589
            $this->queryParametersContainer->set('bq', $boostQuery);
590
            return;
591
        }
592
        $this->queryParametersContainer->setWhenStringOrUnsetWhenEmpty('bq', $boostQuery);
593
    }
594
595
    /**
596
     * Set the tie breaker (tie) parameter
597
     *
598
     * @param mixed $tieParameter tie breaker parameter as string or boolean FALSE to disable / reset the tie parameter
599
     * @return void
600
     */
601
    public function setTieParameter($tieParameter)
602
    {
603
        $this->queryParametersContainer->setWhenStringOrUnsetWhenEmpty('tie', $tieParameter);
604
    }
605
606
    /**
607
     * Gets a specific query parameter by its name.
608
     *
609
     * @param string $parameterName The parameter to return
610
     * @param mixed $defaultIfEmpty
611
     * @return mixed The parameter's value or $defaultIfEmpty if not set
612
     */
613
    public function getQueryParameter($parameterName, $defaultIfEmpty = null)
614
    {
615
        $parameters = $this->getQueryParameters();
616
        return isset($parameters[$parameterName]) ? $parameters[$parameterName] : $defaultIfEmpty;
617
    }
618
619
    /**
620
     * The build method calls build on all ParameterBuilder that fill the QueryParameterContainer
621
     *
622
     * @return void
623
     */
624
    protected function build()
625
    {
626
        $this->getQueryFields()->build($this);
627
        $this->getPhraseFields()->build($this);
628
        $this->getBigramPhraseFields()->build($this);
629
        $this->getTrigramPhraseFields()->build($this);
630
        $this->getHighlighting()->build($this);
631
        $this->getFaceting()->build($this);
632
        $this->getGrouping()->build($this);
633
        $this->getSpellchecking()->build($this);
634
        $this->getFieldCollapsing()->build($this);
635
        $this->getElevation()->build($this);
636
637
        $this->debug->build($this);
638
        $this->sorting->build($this);
639
        $this->operator->build($this);
640
        $this->slops->build($this);
641
642
        // it is important that this parameters get build in the end because other builders add filters and return fields
643
        $this->getReturnFields()->build($this);
644
        $this->getFilters()->build($this);
645
    }
646
647
    /**
648
     * Builds an array of query parameters to use for the search query.
649
     *
650
     * @return array An array ready to use with query parameters
651
     */
652
    public function getQueryParameters()
653
    {
654
        $this->build();
655
        return $this->queryParametersContainer->toArray();
656
    }
657
658
    /**
659
     * @return QueryParametersContainer
660
     */
661
    public function getQueryParametersContainer(): QueryParametersContainer
662
    {
663
        return $this->queryParametersContainer;
664
    }
665
666
    /**
667
     * Adds a parameter to the query.
668
     *
669
     * @param string $parameterName
670
     * @param mixed $value
671
     */
672
    public function addQueryParameter($parameterName, $value)
673
    {
674
        $this->queryParametersContainer->set($parameterName, $value);
675
    }
676
677
    // general query parameters
678
679
    /**
680
     * Enables or disables highlighting of search terms in result teasers.
681
     *
682
     * @param Highlighting $highlighting
683
     * @see http://wiki.apache.org/solr/HighlightingParameters
684
     * @return void
685
     */
686
    public function setHighlighting(Highlighting $highlighting)
687
    {
688
        $this->highlighting = $highlighting;
689
    }
690
691
    /**
692
     * @return Highlighting
693
     */
694
    public function getHighlighting(): Highlighting
695
    {
696
        return $this->highlighting;
697
    }
698
699
    // misc
700
    /**
701
     * @param Spellchecking $spellchecking
702
     */
703
    public function setSpellchecking(Spellchecking $spellchecking)
704
    {
705
        $this->spellchecking = $spellchecking;
706
    }
707
708
    /**
709
     * @return Spellchecking
710
     */
711
    public function getSpellchecking(): Spellchecking
712
    {
713
        return $this->spellchecking;
714
    }
715
716
    /**
717
     * Sets the sort parameter.
718
     *
719
     * $sorting must include a field name (or the pseudo-field score),
720
     * followed by a space,
721
     * followed by a sort direction (asc or desc).
722
     *
723
     * Multiple fallback sortings can be separated by comma,
724
     * ie: <field name> <direction>[,<field name> <direction>]...
725
     *
726
     * @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)
727
     * @see http://wiki.apache.org/solr/CommonQueryParameters#sort
728
     */
729
    public function setSorting($sorting)
730
    {
731
        $sorting = trim((string)$sorting);
732
        $enabled = $sorting !== '';
733
        $this->sorting->setIsEnabled($enabled);
734
        $this->sorting->setSortField($sorting);
735
    }
736
737
    /**
738
     * Enables or disables the debug parameter for the query.
739
     *
740
     * @param bool $debugMode Enables debugging when set to TRUE, deactivates debugging when set to FALSE, defaults to TRUE.
741
     */
742
    public function setDebugMode($debugMode = true)
743
    {
744
        $this->debug->setIsEnabled($debugMode);
745
    }
746
}
747