1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
namespace ApacheSolrForTypo3\Solr\Domain\Search\ResultSet; |
4
|
|
|
|
5
|
|
|
/*************************************************************** |
6
|
|
|
* Copyright notice |
7
|
|
|
* |
8
|
|
|
* (c) 2015-2016 Timo Schmidt <[email protected]> |
9
|
|
|
* All rights reserved |
10
|
|
|
* |
11
|
|
|
* This script is part of the TYPO3 project. The TYPO3 project is |
12
|
|
|
* free software; you can redistribute it and/or modify |
13
|
|
|
* it under the terms of the GNU General Public License as published by |
14
|
|
|
* the Free Software Foundation; either version 3 of the License, or |
15
|
|
|
* (at your option) any later version. |
16
|
|
|
* |
17
|
|
|
* The GNU General Public License can be found at |
18
|
|
|
* http://www.gnu.org/copyleft/gpl.html. |
19
|
|
|
* |
20
|
|
|
* This script is distributed in the hope that it will be useful, |
21
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
22
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
23
|
|
|
* GNU General Public License for more details. |
24
|
|
|
* |
25
|
|
|
* This copyright notice MUST APPEAR in all copies of the script! |
26
|
|
|
***************************************************************/ |
27
|
|
|
|
28
|
|
|
use ApacheSolrForTypo3\Solr\Domain\Search\Query\ParameterBuilder\QueryFields; |
29
|
|
|
use ApacheSolrForTypo3\Solr\Domain\Search\Query\QueryBuilder; |
30
|
|
|
use ApacheSolrForTypo3\Solr\Domain\Search\Query\Query; |
31
|
|
|
use ApacheSolrForTypo3\Solr\Domain\Search\Query\SearchQuery; |
32
|
|
|
use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Result\Parser\ResultParserRegistry; |
33
|
|
|
use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Result\SearchResult; |
34
|
|
|
use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Result\SearchResultCollection; |
35
|
|
|
use ApacheSolrForTypo3\Solr\Domain\Search\SearchRequest; |
36
|
|
|
use ApacheSolrForTypo3\Solr\Domain\Search\SearchRequestAware; |
37
|
|
|
use ApacheSolrForTypo3\Solr\Domain\Variants\VariantsProcessor; |
38
|
|
|
use ApacheSolrForTypo3\Solr\Query\Modifier\Modifier; |
39
|
|
|
use ApacheSolrForTypo3\Solr\Search; |
40
|
|
|
use ApacheSolrForTypo3\Solr\Search\QueryAware; |
41
|
|
|
use ApacheSolrForTypo3\Solr\Search\SearchAware; |
42
|
|
|
use ApacheSolrForTypo3\Solr\Search\SearchComponentManager; |
43
|
|
|
use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration; |
44
|
|
|
use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager; |
45
|
|
|
use ApacheSolrForTypo3\Solr\System\Solr\Document\Document; |
46
|
|
|
use ApacheSolrForTypo3\Solr\System\Solr\ResponseAdapter; |
47
|
|
|
use ApacheSolrForTypo3\Solr\System\Solr\SolrIncompleteResponseException; |
48
|
|
|
use TYPO3\CMS\Core\Utility\GeneralUtility; |
49
|
|
|
use ApacheSolrForTypo3\Solr\Domain\Search\ResultSet\Result\SearchResultBuilder; |
50
|
|
|
use TYPO3\CMS\Extbase\Object\ObjectManager; |
51
|
|
|
use TYPO3\CMS\Extbase\Object\ObjectManagerInterface; |
52
|
|
|
|
53
|
|
|
/** |
54
|
|
|
* The SearchResultSetService is responsible to build a SearchResultSet from a SearchRequest. |
55
|
|
|
* It encapsulates the logic to trigger a search in order to be able to reuse it in multiple places. |
56
|
|
|
* |
57
|
|
|
* @author Timo Schmidt <[email protected]> |
58
|
|
|
*/ |
59
|
|
|
class SearchResultSetService |
60
|
|
|
{ |
61
|
|
|
|
62
|
|
|
/** |
63
|
|
|
* Track, if the number of results per page has been changed by the current request |
64
|
|
|
* |
65
|
|
|
* @var bool |
66
|
|
|
*/ |
67
|
|
|
protected $resultsPerPageChanged = false; |
68
|
|
|
|
69
|
|
|
/** |
70
|
|
|
* @var Search |
71
|
|
|
*/ |
72
|
|
|
protected $search; |
73
|
|
|
|
74
|
|
|
/** |
75
|
|
|
* @var SearchResultSet |
76
|
|
|
*/ |
77
|
|
|
protected $lastResultSet = null; |
78
|
|
|
|
79
|
|
|
/** |
80
|
|
|
* @var boolean |
81
|
|
|
*/ |
82
|
|
|
protected $isSolrAvailable = false; |
83
|
|
|
|
84
|
|
|
/** |
85
|
|
|
* @var TypoScriptConfiguration |
86
|
|
|
*/ |
87
|
|
|
protected $typoScriptConfiguration; |
88
|
|
|
|
89
|
|
|
/** |
90
|
|
|
* @var SolrLogManager |
91
|
|
|
*/ |
92
|
|
|
protected $logger = null; |
93
|
|
|
|
94
|
|
|
/** |
95
|
|
|
* @var SearchResultBuilder |
96
|
|
|
*/ |
97
|
|
|
protected $searchResultBuilder; |
98
|
|
|
|
99
|
|
|
/** |
100
|
|
|
* @var QueryBuilder |
101
|
|
|
*/ |
102
|
|
|
protected $queryBuilder; |
103
|
|
|
|
104
|
|
|
/** |
105
|
|
|
* @var ObjectManagerInterface |
106
|
|
|
*/ |
107
|
|
|
protected $objectManager; |
108
|
|
|
|
109
|
|
|
/** |
110
|
|
|
* @param TypoScriptConfiguration $configuration |
111
|
|
|
* @param Search $search |
112
|
|
|
* @param SolrLogManager $solrLogManager |
113
|
|
|
* @param SearchResultBuilder $resultBuilder |
114
|
|
|
* @param QueryBuilder $queryBuilder |
115
|
|
|
*/ |
116
|
14 |
|
public function __construct(TypoScriptConfiguration $configuration, Search $search, SolrLogManager $solrLogManager = null, SearchResultBuilder $resultBuilder = null, QueryBuilder $queryBuilder = null) |
117
|
|
|
{ |
118
|
14 |
|
$this->search = $search; |
119
|
14 |
|
$this->typoScriptConfiguration = $configuration; |
120
|
14 |
|
$this->logger = $solrLogManager ?? GeneralUtility::makeInstance(SolrLogManager::class, /** @scrutinizer ignore-type */ __CLASS__); |
121
|
14 |
|
$this->searchResultBuilder = $resultBuilder ?? GeneralUtility::makeInstance(SearchResultBuilder::class); |
122
|
14 |
|
$this->queryBuilder = $queryBuilder ?? GeneralUtility::makeInstance(QueryBuilder::class, /** @scrutinizer ignore-type */ $configuration, /** @scrutinizer ignore-type */ $solrLogManager); |
123
|
14 |
|
} |
124
|
|
|
|
125
|
|
|
/** |
126
|
|
|
* @param ObjectManagerInterface $objectManager |
127
|
|
|
*/ |
128
|
13 |
|
public function injectObjectManager(ObjectManagerInterface $objectManager) |
129
|
|
|
{ |
130
|
13 |
|
$this->objectManager = $objectManager; |
131
|
13 |
|
} |
132
|
|
|
|
133
|
|
|
/** |
134
|
|
|
* @param bool $useCache |
135
|
|
|
* @return bool |
136
|
|
|
*/ |
137
|
|
|
public function getIsSolrAvailable($useCache = true) |
138
|
|
|
{ |
139
|
|
|
$this->isSolrAvailable = $this->search->ping($useCache); |
140
|
|
|
return $this->isSolrAvailable; |
141
|
|
|
} |
142
|
|
|
|
143
|
|
|
/** |
144
|
|
|
* Retrieves the used search instance. |
145
|
|
|
* |
146
|
|
|
* @return Search |
147
|
|
|
*/ |
148
|
|
|
public function getSearch() |
149
|
|
|
{ |
150
|
|
|
return $this->search; |
151
|
|
|
} |
152
|
|
|
|
153
|
|
|
/** |
154
|
|
|
* @param Query $query |
155
|
|
|
* @param SearchRequest $searchRequest |
156
|
|
|
*/ |
157
|
11 |
|
protected function initializeRegisteredSearchComponents(Query $query, SearchRequest $searchRequest) |
158
|
|
|
{ |
159
|
11 |
|
$searchComponents = $this->getRegisteredSearchComponents(); |
160
|
|
|
|
161
|
11 |
|
foreach ($searchComponents as $searchComponent) { |
162
|
|
|
/** @var Search\SearchComponent $searchComponent */ |
163
|
6 |
|
$searchComponent->setSearchConfiguration($this->typoScriptConfiguration->getSearchConfiguration()); |
164
|
|
|
|
165
|
6 |
|
if ($searchComponent instanceof QueryAware) { |
166
|
6 |
|
$searchComponent->setQuery($query); |
167
|
|
|
} |
168
|
|
|
|
169
|
6 |
|
if ($searchComponent instanceof SearchRequestAware) { |
170
|
5 |
|
$searchComponent->setSearchRequest($searchRequest); |
171
|
|
|
} |
172
|
|
|
|
173
|
6 |
|
$searchComponent->initializeSearchComponent(); |
174
|
|
|
} |
175
|
11 |
|
} |
176
|
|
|
|
177
|
|
|
/** |
178
|
|
|
* @return string |
179
|
|
|
*/ |
180
|
13 |
|
protected function getResultSetClassName() |
181
|
|
|
{ |
182
|
13 |
|
return isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['searchResultSetClassName ']) ? |
183
|
13 |
|
$GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['searchResultSetClassName '] : SearchResultSet::class; |
184
|
|
|
} |
185
|
|
|
|
186
|
|
|
/** |
187
|
|
|
* Performs a search and returns a SearchResultSet. |
188
|
|
|
* |
189
|
|
|
* @param SearchRequest $searchRequest |
190
|
|
|
* @return SearchResultSet |
191
|
|
|
*/ |
192
|
13 |
|
public function search(SearchRequest $searchRequest) |
193
|
|
|
{ |
194
|
13 |
|
$resultSet = $this->getInitializedSearchResultSet($searchRequest); |
195
|
13 |
|
$this->lastResultSet = $resultSet; |
196
|
|
|
|
197
|
13 |
|
$resultSet = $this->handleSearchHook('beforeSearch', $resultSet); |
198
|
13 |
|
if ($this->shouldReturnEmptyResultSetWithoutExecutedSearch($searchRequest)) { |
199
|
2 |
|
$resultSet->setHasSearched(false); |
200
|
2 |
|
return $resultSet; |
201
|
|
|
} |
202
|
|
|
|
203
|
11 |
|
$query = $this->queryBuilder->buildSearchQuery($searchRequest->getRawUserQuery(), (int)$searchRequest->getResultsPerPage(), $searchRequest->getAdditionalFilters()); |
204
|
11 |
|
$this->initializeRegisteredSearchComponents($query, $searchRequest); |
205
|
11 |
|
$resultSet->setUsedQuery($query); |
206
|
|
|
|
207
|
|
|
// performing the actual search, sending the query to the Solr server |
208
|
11 |
|
$query = $this->modifyQuery($query, $searchRequest, $this->search); |
209
|
11 |
|
$response = $this->doASearch($query, $searchRequest); |
210
|
|
|
|
211
|
11 |
|
if ((int)$searchRequest->getResultsPerPage() === 0) { |
212
|
|
|
// when resultPerPage was forced to 0 we also set the numFound to 0 to hide results, e.g. |
213
|
|
|
// when results for the initial search should not be shown. |
214
|
|
|
// @extensionScannerIgnoreLine |
215
|
|
|
$response->response->numFound = 0; |
216
|
|
|
} |
217
|
|
|
|
218
|
11 |
|
$resultSet->setHasSearched(true); |
219
|
11 |
|
$resultSet->setResponse($response); |
220
|
|
|
|
221
|
11 |
|
$this->getParsedSearchResults($resultSet); |
222
|
|
|
|
223
|
11 |
|
$resultSet->setUsedAdditionalFilters($this->queryBuilder->getAdditionalFilters()); |
224
|
|
|
|
225
|
|
|
/** @var $variantsProcessor VariantsProcessor */ |
226
|
11 |
|
$variantsProcessor = GeneralUtility::makeInstance( |
227
|
11 |
|
VariantsProcessor::class, |
228
|
11 |
|
/** @scrutinizer ignore-type */ $this->typoScriptConfiguration, |
229
|
11 |
|
/** @scrutinizer ignore-type */ $this->searchResultBuilder |
230
|
|
|
); |
231
|
11 |
|
$variantsProcessor->process($resultSet); |
232
|
|
|
|
233
|
|
|
/** @var $searchResultReconstitutionProcessor ResultSetReconstitutionProcessor */ |
234
|
11 |
|
$searchResultReconstitutionProcessor = GeneralUtility::makeInstance(ResultSetReconstitutionProcessor::class); |
235
|
11 |
|
$searchResultReconstitutionProcessor->process($resultSet); |
236
|
|
|
|
237
|
11 |
|
$resultSet = $this->getAutoCorrection($resultSet); |
238
|
|
|
|
239
|
11 |
|
return $this->handleSearchHook('afterSearch', $resultSet); |
240
|
|
|
} |
241
|
|
|
|
242
|
|
|
/** |
243
|
|
|
* Uses the configured parser and retrieves the parsed search results. |
244
|
|
|
* |
245
|
|
|
* @param SearchResultSet $resultSet |
246
|
|
|
*/ |
247
|
11 |
|
protected function getParsedSearchResults($resultSet) |
248
|
|
|
{ |
249
|
|
|
/** @var ResultParserRegistry $parserRegistry */ |
250
|
11 |
|
$parserRegistry = GeneralUtility::makeInstance(ResultParserRegistry::class, /** @scrutinizer ignore-type */ $this->typoScriptConfiguration); |
251
|
11 |
|
$useRawDocuments = (bool)$this->typoScriptConfiguration->getValueByPathOrDefaultValue('plugin.tx_solr.features.useRawDocuments', false); |
252
|
11 |
|
$parserRegistry->getParser($resultSet)->parse($resultSet, $useRawDocuments); |
253
|
11 |
|
} |
254
|
|
|
|
255
|
|
|
/** |
256
|
|
|
* Evaluates conditions on the request and configuration and returns true if no search should be triggered and an empty |
257
|
|
|
* SearchResultSet should be returned. |
258
|
|
|
* |
259
|
|
|
* @param SearchRequest $searchRequest |
260
|
|
|
* @return bool |
261
|
|
|
*/ |
262
|
13 |
|
protected function shouldReturnEmptyResultSetWithoutExecutedSearch(SearchRequest $searchRequest) |
263
|
|
|
{ |
264
|
13 |
|
if ($searchRequest->getRawUserQueryIsNull() && !$this->getInitialSearchIsConfigured()) { |
265
|
|
|
// when no rawQuery was passed or no initialSearch is configured, we pass an empty result set |
266
|
1 |
|
return true; |
267
|
|
|
} |
268
|
|
|
|
269
|
12 |
|
if ($searchRequest->getRawUserQueryIsEmptyString() && !$this->typoScriptConfiguration->getSearchQueryAllowEmptyQuery()) { |
270
|
|
|
// the user entered an empty query string "" or " " and empty querystring is not allowed |
271
|
1 |
|
return true; |
272
|
|
|
} |
273
|
|
|
|
274
|
11 |
|
return false; |
275
|
|
|
} |
276
|
|
|
|
277
|
|
|
/** |
278
|
|
|
* Initializes the SearchResultSet from the SearchRequest |
279
|
|
|
* |
280
|
|
|
* @param SearchRequest $searchRequest |
281
|
|
|
* @return SearchResultSet |
282
|
|
|
*/ |
283
|
13 |
|
protected function getInitializedSearchResultSet(SearchRequest $searchRequest):SearchResultSet |
284
|
|
|
{ |
285
|
|
|
/** @var $resultSet SearchResultSet */ |
286
|
13 |
|
$resultSetClass = $this->getResultSetClassName(); |
287
|
13 |
|
$resultSet = $this->objectManager->get($resultSetClass); |
|
|
|
|
288
|
|
|
|
289
|
13 |
|
$resultSet->setUsedSearchRequest($searchRequest); |
290
|
13 |
|
$resultSet->setUsedPage((int)$searchRequest->getPage()); |
291
|
13 |
|
$resultSet->setUsedResultsPerPage((int)$searchRequest->getResultsPerPage()); |
292
|
13 |
|
$resultSet->setUsedSearch($this->search); |
293
|
13 |
|
return $resultSet; |
294
|
|
|
} |
295
|
|
|
|
296
|
|
|
/** |
297
|
|
|
* Executes the search and builds a fake response for a current bug in Apache Solr 6.3 |
298
|
|
|
* |
299
|
|
|
* @param Query $query |
300
|
|
|
* @param SearchRequest $searchRequest |
301
|
|
|
* @return ResponseAdapter |
302
|
|
|
*/ |
303
|
11 |
|
protected function doASearch($query, $searchRequest): ResponseAdapter |
304
|
|
|
{ |
305
|
|
|
// the offset mulitplier is page - 1 but not less then zero |
306
|
11 |
|
$offsetMultiplier = max(0, $searchRequest->getPage() - 1); |
307
|
11 |
|
$offSet = $offsetMultiplier * (int)$searchRequest->getResultsPerPage(); |
308
|
|
|
|
309
|
11 |
|
$response = $this->search->search($query, $offSet, null); |
310
|
11 |
|
if($response === null) { |
311
|
|
|
throw new SolrIncompleteResponseException('The response retrieved from solr was incomplete', 1505989678); |
312
|
|
|
} |
313
|
|
|
|
314
|
11 |
|
return $response; |
315
|
|
|
} |
316
|
|
|
|
317
|
|
|
/** |
318
|
|
|
* @param SearchResultSet $searchResultSet |
319
|
|
|
* @return SearchResultSet |
320
|
|
|
*/ |
321
|
11 |
|
protected function getAutoCorrection(SearchResultSet $searchResultSet) |
322
|
|
|
{ |
323
|
|
|
// no secondary search configured |
324
|
11 |
|
if (!$this->typoScriptConfiguration->getSearchSpellcheckingSearchUsingSpellCheckerSuggestion()) { |
325
|
11 |
|
return $searchResultSet; |
326
|
|
|
} |
327
|
|
|
|
328
|
|
|
// more then zero results |
329
|
|
|
if ($searchResultSet->getAllResultCount() > 0) { |
330
|
|
|
return $searchResultSet; |
331
|
|
|
} |
332
|
|
|
|
333
|
|
|
// no corrections present |
334
|
|
|
if (!$searchResultSet->getHasSpellCheckingSuggestions()) { |
335
|
|
|
return $searchResultSet; |
336
|
|
|
} |
337
|
|
|
|
338
|
|
|
$searchResultSet = $this->peformAutoCorrection($searchResultSet); |
339
|
|
|
|
340
|
|
|
return $searchResultSet; |
341
|
|
|
} |
342
|
|
|
|
343
|
|
|
/** |
344
|
|
|
* @param SearchResultSet $searchResultSet |
345
|
|
|
* @return SearchResultSet |
346
|
|
|
*/ |
347
|
|
|
protected function peformAutoCorrection(SearchResultSet $searchResultSet) |
348
|
|
|
{ |
349
|
|
|
$searchRequest = $searchResultSet->getUsedSearchRequest(); |
350
|
|
|
$suggestions = $searchResultSet->getSpellCheckingSuggestions(); |
351
|
|
|
|
352
|
|
|
$maximumRuns = $this->typoScriptConfiguration->getSearchSpellcheckingNumberOfSuggestionsToTry(1); |
353
|
|
|
$runs = 0; |
354
|
|
|
|
355
|
|
|
foreach ($suggestions as $suggestion) { |
356
|
|
|
$runs++; |
357
|
|
|
|
358
|
|
|
$correction = $suggestion->getSuggestion(); |
359
|
|
|
$initialQuery = $searchRequest->getRawUserQuery(); |
360
|
|
|
|
361
|
|
|
$searchRequest->setRawQueryString($correction); |
362
|
|
|
$searchResultSet = $this->search($searchRequest); |
363
|
|
|
if ($searchResultSet->getAllResultCount() > 0) { |
364
|
|
|
$searchResultSet->setIsAutoCorrected(true); |
365
|
|
|
$searchResultSet->setCorrectedQueryString($correction); |
366
|
|
|
$searchResultSet->setInitialQueryString($initialQuery); |
367
|
|
|
break; |
368
|
|
|
} |
369
|
|
|
|
370
|
|
|
if ($runs > $maximumRuns) { |
371
|
|
|
break; |
372
|
|
|
} |
373
|
|
|
} |
374
|
|
|
return $searchResultSet; |
375
|
|
|
} |
376
|
|
|
|
377
|
|
|
/** |
378
|
|
|
* Allows to modify a query before eventually handing it over to Solr. |
379
|
|
|
* |
380
|
|
|
* @param Query $query The current query before it's being handed over to Solr. |
381
|
|
|
* @param SearchRequest $searchRequest The searchRequest, relevant in the current context |
382
|
|
|
* @param Search $search The search, relevant in the current context |
383
|
|
|
* @throws \UnexpectedValueException |
384
|
|
|
* @return Query The modified query that is actually going to be given to Solr. |
385
|
|
|
*/ |
386
|
11 |
|
protected function modifyQuery(Query $query, SearchRequest $searchRequest, Search $search) |
387
|
|
|
{ |
388
|
|
|
// hook to modify the search query |
389
|
11 |
|
if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['modifySearchQuery'])) { |
390
|
5 |
|
foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['modifySearchQuery'] as $classReference) { |
391
|
5 |
|
$queryModifier = $this->objectManager->get($classReference); |
|
|
|
|
392
|
|
|
|
393
|
5 |
|
if ($queryModifier instanceof Modifier) { |
394
|
5 |
|
if ($queryModifier instanceof SearchAware) { |
395
|
|
|
$queryModifier->setSearch($search); |
396
|
|
|
} |
397
|
|
|
|
398
|
5 |
|
if ($queryModifier instanceof SearchRequestAware) { |
399
|
|
|
$queryModifier->setSearchRequest($searchRequest); |
400
|
|
|
} |
401
|
|
|
|
402
|
5 |
|
$query = $queryModifier->modifyQuery($query); |
403
|
|
|
} else { |
404
|
|
|
throw new \UnexpectedValueException( |
405
|
|
|
get_class($queryModifier) . ' must implement interface ' . Modifier::class, |
406
|
|
|
1310387414 |
407
|
|
|
); |
408
|
|
|
} |
409
|
|
|
} |
410
|
|
|
} |
411
|
|
|
|
412
|
11 |
|
return $query; |
413
|
|
|
} |
414
|
|
|
|
415
|
|
|
/** |
416
|
|
|
* Retrieves a single document from solr by document id. |
417
|
|
|
* |
418
|
|
|
* @param string $documentId |
419
|
|
|
* @return SearchResult |
420
|
|
|
*/ |
421
|
1 |
|
public function getDocumentById($documentId) |
422
|
|
|
{ |
423
|
|
|
/* @var $query SearchQuery */ |
424
|
1 |
|
$query = $this->queryBuilder->newSearchQuery($documentId)->useQueryFields(QueryFields::fromString('id'))->getQuery(); |
425
|
1 |
|
$response = $this->search->search($query, 0, 1); |
426
|
1 |
|
$parsedData = $response->getParsedData(); |
427
|
|
|
// @extensionScannerIgnoreLine |
428
|
1 |
|
$resultDocument = isset($parsedData->response->docs[0]) ? $parsedData->response->docs[0] : null; |
429
|
|
|
|
430
|
1 |
|
if (!$resultDocument instanceof Document) { |
431
|
|
|
throw new \UnexpectedValueException("Response did not contain a valid Document object"); |
432
|
|
|
} |
433
|
|
|
|
434
|
1 |
|
return $this->searchResultBuilder->fromApacheSolrDocument($resultDocument); |
435
|
|
|
} |
436
|
|
|
|
437
|
|
|
/** |
438
|
|
|
* This method is used to call the registered hooks during the search execution. |
439
|
|
|
* |
440
|
|
|
* @param string $eventName |
441
|
|
|
* @param SearchResultSet $resultSet |
442
|
|
|
* @return SearchResultSet |
443
|
|
|
*/ |
444
|
13 |
|
private function handleSearchHook($eventName, SearchResultSet $resultSet) |
445
|
|
|
{ |
446
|
13 |
|
if (!is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr'][$eventName])) { |
447
|
13 |
|
return $resultSet; |
448
|
|
|
} |
449
|
|
|
|
450
|
1 |
|
foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr'][$eventName] as $classReference) { |
451
|
1 |
|
$afterSearchProcessor = $this->objectManager->get($classReference); |
|
|
|
|
452
|
1 |
|
if ($afterSearchProcessor instanceof SearchResultSetProcessor) { |
453
|
1 |
|
$afterSearchProcessor->process($resultSet); |
454
|
|
|
} |
455
|
|
|
} |
456
|
|
|
|
457
|
1 |
|
return $resultSet; |
458
|
|
|
} |
459
|
|
|
|
460
|
|
|
/** |
461
|
|
|
* @return SearchResultSet |
462
|
|
|
*/ |
463
|
|
|
public function getLastResultSet() |
464
|
|
|
{ |
465
|
|
|
return $this->lastResultSet; |
466
|
|
|
} |
467
|
|
|
|
468
|
|
|
/** |
469
|
|
|
* This method returns true when the last search was executed with an empty query |
470
|
|
|
* string or whitespaces only. When no search was triggered it will return false. |
471
|
|
|
* |
472
|
|
|
* @return bool |
473
|
|
|
*/ |
474
|
|
|
public function getLastSearchWasExecutedWithEmptyQueryString() |
475
|
|
|
{ |
476
|
|
|
$wasEmptyQueryString = false; |
477
|
|
|
if ($this->lastResultSet != null) { |
478
|
|
|
$wasEmptyQueryString = $this->lastResultSet->getUsedSearchRequest()->getRawUserQueryIsEmptyString(); |
479
|
|
|
} |
480
|
|
|
|
481
|
|
|
return $wasEmptyQueryString; |
482
|
|
|
} |
483
|
|
|
|
484
|
|
|
/** |
485
|
|
|
* @return bool |
486
|
|
|
*/ |
487
|
1 |
|
protected function getInitialSearchIsConfigured() |
488
|
|
|
{ |
489
|
1 |
|
return $this->typoScriptConfiguration->getSearchInitializeWithEmptyQuery() || $this->typoScriptConfiguration->getSearchShowResultsOfInitialEmptyQuery() || $this->typoScriptConfiguration->getSearchInitializeWithQuery() || $this->typoScriptConfiguration->getSearchShowResultsOfInitialQuery(); |
490
|
|
|
} |
491
|
|
|
|
492
|
|
|
/** |
493
|
|
|
* @return mixed |
494
|
|
|
*/ |
495
|
5 |
|
protected function getRegisteredSearchComponents() |
496
|
|
|
{ |
497
|
5 |
|
return GeneralUtility::makeInstance(SearchComponentManager::class)->getSearchComponents(); |
498
|
|
|
} |
499
|
|
|
} |
500
|
|
|
|
This function has been deprecated. The supplier of the function has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.