Passed
Pull Request — master (#1318)
by
unknown
32:46
created

setUseQueryAwareComponents()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 0
cts 0
cp 0
cc 1
eloc 2
nc 1
nop 1
crap 2
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 2 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\SearchRequest;
29
use ApacheSolrForTypo3\Solr\Query;
30
use ApacheSolrForTypo3\Solr\Response\Processor\ResponseProcessor;
31
use ApacheSolrForTypo3\Solr\Search;
32
use ApacheSolrForTypo3\Solr\Search\QueryAware;
33
use ApacheSolrForTypo3\Solr\Search\SearchComponentManager;
34
use ApacheSolrForTypo3\Solr\System\Configuration\TypoScriptConfiguration;
35
use ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager;
36
use TYPO3\CMS\Core\Utility\GeneralUtility;
37
use TYPO3\CMS\Frontend\ContentObject\ContentObjectRenderer;
38
use Apache_Solr_ParserException;
39
40
/**
41
 * The SearchResultSetService is responsible to build a SearchResultSet from a SearchRequest.
42
 * It encapsulates the logic to trigger a search in order to be able to reuse it in multiple places.
43
 *
44
 * @author Timo Schmidt <[email protected]>
45
 */
46
class SearchResultSetService
47
{
48
    /**
49
     * Additional filters, which will be added to the query, as well as to
50
     * suggest queries.
51
     *
52
     * @var array
53
     */
54
    protected $additionalFilters = [];
55
56
    /**
57
     * Track, if the number of results per page has been changed by the current request
58
     *
59
     * @var bool
60
     */
61
    protected $resultsPerPageChanged = false;
62
63
    /**
64
     * @var \ApacheSolrForTypo3\Solr\Search
65
     */
66
    protected $search;
67
68
    /**
69
     * @var SearchResultSet
70
     */
71
    protected $lastResultSet = null;
72
73
    /**
74
     * @var bool
75
     */
76
    protected $useQueryAwareComponents = true;
77
78
    /**
79
     * @var
80
     */
81
    protected $isSolrAvailable = false;
82
83
    /**
84
     * @var TypoScriptConfiguration
85
     */
86
    protected $typoScriptConfiguration;
87
88
    /**
89
     * @var \ApacheSolrForTypo3\Solr\System\Logging\SolrLogManager;
90
     */
91
    protected $logger = null;
92
93
    /**
94
     * @param TypoScriptConfiguration $configuration
95
     * @param Search $search
96
     */
97
    public function __construct(TypoScriptConfiguration $configuration, Search $search)
98
    {
99
        $this->logger = GeneralUtility::makeInstance(SolrLogManager::class, __CLASS__);
100
        $this->search = $search;
101
        $this->typoScriptConfiguration = $configuration;
102
    }
103
104
    /**
105
     * @param bool $useCache
106
     * @return bool
107
     */
108
    public function getIsSolrAvailable($useCache = true)
109
    {
110
        $this->isSolrAvailable = $this->search->ping($useCache);
111 37
        return $this->isSolrAvailable;
112
    }
113 37
114 37
    /**
115 37
     * @return bool
116 37
     */
117 37
    public function getHasSearched()
118
    {
119
        return $this->search->hasSearched();
120
    }
121
122 1
    /**
123
     * Retrieves the used search instance.
124 1
     *
125
     * @return Search
126
     */
127
    public function getSearch()
128
    {
129
        return $this->search;
130
    }
131 25
132
    /**
133 25
     * @param bool $useQueryAwareComponents
134 25
     */
135
    public function setUseQueryAwareComponents($useQueryAwareComponents)
136
    {
137
        $this->useQueryAwareComponents = $useQueryAwareComponents;
138
    }
139
140 25
    /**
141
     * @return bool
142 25
     */
143
    public function getUseQueryAwareComponents()
144
    {
145
        return $this->useQueryAwareComponents;
146
    }
147
148
    /**
149
     * Initializes the Query object and SearchComponents and returns
150 25
     * the initialized query object, when a search should be executed.
151
     *
152 25
     * @param string $rawQuery
153
     * @param int $resultsPerPage
154
     * @return Query
155
     */
156
    protected function getPreparedQuery($rawQuery, $resultsPerPage)
157
    {
158
        /* @var $query Query */
159
        $query = GeneralUtility::makeInstance(Query::class, $rawQuery);
160
161
        $this->applyPageSectionsRootLineFilter($query);
162
163
        if ($this->typoScriptConfiguration->getLoggingQuerySearchWords()) {
164
            $this->logger->log(
165
                SolrLogManager::INFO,
166
                'Received search query',
167
                [
168
                    $rawQuery
169
                ]
170
            );
171
        }
172
173
        $query->setResultsPerPage($resultsPerPage);
174
175
        $this->initializeRegisteredSearchComponents($query);
176
177
        if ($this->typoScriptConfiguration->getSearchInitializeWithEmptyQuery() || $this->typoScriptConfiguration->getSearchQueryAllowEmptyQuery()) {
178
            // empty main query, but using a "return everything"
179
            // alternative query in q.alt
180
            $query->setAlternativeQuery('*:*');
181
        }
182
183
        if ($this->typoScriptConfiguration->getSearchInitializeWithQuery()) {
184
            $query->setAlternativeQuery($this->typoScriptConfiguration->getSearchInitializeWithQuery());
185
        }
186
187
        foreach ($this->getAdditionalFilters() as $additionalFilter) {
188
            $query->addFilter($additionalFilter);
189
        }
190
191
        return $query;
192
    }
193
194
    /**
195 31
     * @param Query $query
196
     */
197
    protected function initializeRegisteredSearchComponents(Query $query)
198 31
    {
199
        $searchComponents = $this->getRegisteredSearchComponents();
200 31
201
        foreach ($searchComponents as $searchComponent) {
202 31
            /** @var Search\SearchComponent $searchComponent */
203
            $searchComponent->setSearchConfiguration($this->typoScriptConfiguration->getSearchConfiguration());
204
205
            if ($searchComponent instanceof QueryAware && $this->useQueryAwareComponents) {
206
                $searchComponent->setQuery($query);
207
            }
208
209
            $searchComponent->initializeSearchComponent();
210
        }
211
    }
212 31
213
    /**
214 31
     * Returns the number of results per Page.
215
     *
216 31
     * Also influences how many result documents are returned by the Solr
217
     * server as the return value is used in the Solr "rows" GET parameter.
218
     *
219 24
     * @param string $rawQuery
220
     * @param int|null $requestedPerPage
221
     * @return int number of results to show per page
222 31
     */
223 3
    protected function getNumberOfResultsPerPage($rawQuery, $requestedPerPage = null)
224
    {
225
        $perPageSwitchOptions = $this->typoScriptConfiguration->getSearchResultsPerPageSwitchOptionsAsArray();
226 31
        if (isset($requestedPerPage) && in_array($requestedPerPage, $perPageSwitchOptions)) {
227 2
            $this->setPerPageInSession($requestedPerPage);
228
            $this->resultsPerPageChanged = true;
229
        }
230 31
231
        $defaultResultsPerPage = $this->typoScriptConfiguration->getSearchResultsPerPage();
232
        $sessionResultPerPage = $this->getPerPageFromSession();
233
234
        $currentNumberOfResultsShown = $defaultResultsPerPage;
235
        if (!is_null($sessionResultPerPage) && in_array($sessionResultPerPage, $perPageSwitchOptions)) {
236 31
            $currentNumberOfResultsShown = (int)$sessionResultPerPage;
237
        }
238 31
239
        if ($this->shouldHideResultsFromInitialSearch($rawQuery)) {
240 31
            // initialize search with an empty query, which would by default return all documents
241
            // anyway, tell Solr to not return any result documents
242 25
            // Solr will still return facets though
243
            $currentNumberOfResultsShown = 0;
244 25
        }
245 25
246
        return $currentNumberOfResultsShown;
247
    }
248 25
249
    /**
250
     * Provides a hook for other classes to process the search's response.
251
     *
252 25
     * @param string $rawQuery
253
     * @param Query $query The query that has been searched for.
254 31
     * @param \Apache_Solr_Response $response The search's response.
255
     */
256
    protected function processResponse($rawQuery, Query $query, \Apache_Solr_Response $response)
257
    {
258
        if ($this->shouldHideResultsFromInitialSearch($rawQuery)) {
259
            // explicitly set number of results to 0 as we just wanted
260
            // facets and the like according to configuration
261
            // @see getNumberOfResultsPerPage()
262
            $response->response->numFound = 0;
0 ignored issues
show
Bug introduced by
The property response does not seem to exist. Did you mean _response?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
263
        }
264
265
        $this->wrapResultDocumentInResultObject($response);
266 31
        $this->addExpandedDocumentsFromVariants($response);
267
268 31
        if (is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['processSearchResponse'])) {
269 31
            foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['processSearchResponse'] as $classReference) {
270 1
                $responseProcessor = GeneralUtility::getUserObj($classReference);
271 1
                if ($responseProcessor instanceof ResponseProcessor) {
272
                    $responseProcessor->processResponse($query, $response);
273
                }
274 31
            }
275 31
        }
276
    }
277 31
278 31
    /**
279
     * This method is used to add documents to the expanded documents of the SearchResult
280
     * when collapsing is configured.
281
     *
282 31
     * @param \Apache_Solr_Response $response
283
     */
284
    protected function addExpandedDocumentsFromVariants(\Apache_Solr_Response $response)
285
    {
286
        if (!is_array($response->response->docs)) {
0 ignored issues
show
Bug introduced by
The property response does not seem to exist. Did you mean _response?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
287
            return;
288
        }
289 31
290
        if (!$this->typoScriptConfiguration->getSearchVariants()) {
291
            return;
292
        }
293
294
        $variantsField = $this->typoScriptConfiguration->getSearchVariantsField();
295
        foreach ($response->response->docs as $key => $resultDocument) {
0 ignored issues
show
Bug introduced by
The property response does not seem to exist. Did you mean _response?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
296
            /** @var $resultDocument SearchResult */
297
            $variantField = $resultDocument->getField($variantsField);
298
            $variantId = isset($variantField['value']) ? $variantField['value'] : null;
299 32
300
                // when there is no value in the collapsing field, we can return
301 32
            if ($variantId === null) {
302
                continue;
303
            }
304
305
            $variantAccessKey = strtolower($variantId);
306
            if (!isset($response->{'expanded'}) || !isset($response->{'expanded'}->{$variantAccessKey})) {
307
                continue;
308 32
            }
309 32
310
            foreach ($response->{'expanded'}->{$variantAccessKey}->{'docs'} as $variantDocumentArray) {
311 32
                $variantDocument = new \Apache_Solr_Document();
312 21
                foreach (get_object_vars($variantDocumentArray) as $propertyName => $propertyValue) {
313 21
                    $variantDocument->{$propertyName} = $propertyValue;
314 21
                }
315 21
                $variantSearchResult = $this->wrapApacheSolrDocumentInResultObject($variantDocument);
316
                $variantSearchResult->setIsVariant(true);
317
                $variantSearchResult->setVariantParent($resultDocument);
318
319 32
                $resultDocument->addVariant($variantSearchResult);
320
            }
321
        }
322
    }
323
324
    /**
325
     * Wrap all results document it a custom EXT:solr SearchResult object.
326
     *
327 32
     * Can be overwritten:
328
     *
329 32
     * $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['searchResultClassName '] = ''
330 5
     *
331
     * to use a custom result object.
332
     *
333 27
     * @param \Apache_Solr_Response $response
334 24
     * @throws \Apache_Solr_ParserException
335
     */
336
    protected function wrapResultDocumentInResultObject(\Apache_Solr_Response $response)
337 3
    {
338 3
        $documents = $response->response->docs;
0 ignored issues
show
Bug introduced by
The property response does not seem to exist. Did you mean _response?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
339
340 2
        if (!is_array($documents)) {
341 2
            return;
342
        }
343
344 2
        foreach ($documents as $key => $originalDocument) {
345
            $result = $this->wrapApacheSolrDocumentInResultObject($originalDocument);
346
            $documents[$key] = $result;
347
        }
348 2
349 2
        $response->response->docs = $documents;
0 ignored issues
show
Bug introduced by
The property response does not seem to exist. Did you mean _response?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
350
    }
351
352
    /**
353 2
     * This method is used to wrap the \Apache_Solr_Document instance in an instance of the configured SearchResult
354 2
     * class.
355 2
     *
356 2
     * @param \Apache_Solr_Document $originalDocument
357
     * @throws \InvalidArgumentException
358 2
     * @return SearchResult
359 2
     */
360 2
    protected function wrapApacheSolrDocumentInResultObject(\Apache_Solr_Document $originalDocument)
361
    {
362 2
        $searchResultClassName = $this->getResultClassName();
363
        $result = GeneralUtility::makeInstance($searchResultClassName, $originalDocument);
364
        if (!$result instanceof SearchResult) {
365 3
            throw new \InvalidArgumentException('Could not create result object with class: ' . (string)$searchResultClassName, 1470037679);
366
        }
367
368
        return $result;
369
    }
370
371
    /**
372
     * @return string
373
     */
374
    protected function getResultClassName()
375
    {
376
        return isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['searchResultClassName ']) ?
377
            $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['searchResultClassName '] : SearchResult::class;
378
    }
379 32
380
    /**
381
     * @return string
382 32
     */
383 1
    protected function getResultSetClassName()
384
    {
385
        return isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['searchResultSetClassName ']) ?
386
            $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr']['searchResultSetClassName '] : SearchResultSet::class;
387
    }
388 1
389
    /**
390
     * Checks it the results should be hidden in the response.
391
     *
392 1
     * @param string $rawQuery
393 1
     * @return bool
394 1
     */
395 1
    protected function shouldHideResultsFromInitialSearch($rawQuery)
396 1
    {
397
        return ($this->typoScriptConfiguration->getSearchInitializeWithEmptyQuery() || $this->typoScriptConfiguration->getSearchInitializeWithQuery()) && !$this->typoScriptConfiguration->getSearchShowResultsOfInitialEmptyQuery() && !$this->typoScriptConfiguration->getSearchShowResultsOfInitialQuery() && $rawQuery === null;
398 1
    }
399
400
    /**
401 32
     * Initializes additional filters configured through TypoScript and
402 5
     * Flexforms for use in regular queries and suggest queries.
403
     *
404
     * @param Query $query
405 27
     * @return void
406 24
     */
407 24
    protected function applyPageSectionsRootLineFilter(Query $query)
408
    {
409
        $searchQueryFilters = $this->typoScriptConfiguration->getSearchQueryFilterConfiguration();
410 27
        if (count($searchQueryFilters) <= 0) {
411 27
            return;
412
        }
413
414
        // special filter to limit search to specific page tree branches
415
        if (array_key_exists('__pageSections', $searchQueryFilters)) {
416
            $query->setRootlineFilter($searchQueryFilters['__pageSections']);
417
            $this->typoScriptConfiguration->removeSearchQueryFilterForPageSections();
418
        }
419
    }
420
421 24
    /**
422
     * Retrieves the configuration filters from the TypoScript configuration, except the __pageSections filter.
423 24
     *
424 24
     * @return array
425 24
     */
426
    public function getAdditionalFilters()
427
    {
428
        // when we've build the additionalFilter once, we could return them
429 24
        if (count($this->additionalFilters) > 0) {
430
            return $this->additionalFilters;
431
        }
432
433
        $searchQueryFilters = $this->typoScriptConfiguration->getSearchQueryFilterConfiguration();
434
        if (count($searchQueryFilters) <= 0) {
435 24
            return [];
436
        }
437 24
438 24
        $cObj = GeneralUtility::makeInstance(ContentObjectRenderer::class);
439
440
        // all other regular filters
441
        foreach ($searchQueryFilters as $filterKey => $filter) {
442
            // the __pageSections filter should not be handled as additional filter
443
            if ($filterKey === '__pageSections') {
444 34
                continue;
445
            }
446 34
447 34
            $filterIsArray = is_array($searchQueryFilters[$filterKey]);
448
            if ($filterIsArray) {
449
                continue;
450
            }
451
452
            $hasSubConfiguration = is_array($searchQueryFilters[$filterKey . '.']);
453
            if ($hasSubConfiguration) {
454
                $filter = $cObj->stdWrap($searchQueryFilters[$filterKey], $searchQueryFilters[$filterKey . '.']);
455
            }
456 32
457
            $this->additionalFilters[$filterKey] = $filter;
458 32
        }
459
460
        return $this->additionalFilters;
461
    }
462
463
    /**
464
     * Performs a search and returns a SearchResultSet.
465
     *
466
     * @param SearchRequest $searchRequest
467
     * @return SearchResultSet
468 31
     */
469
    public function search(SearchRequest $searchRequest)
470 31
    {
471 31
        /** @var $resultSet SearchResultSet */
472 29
        $resultSetClass = $this->getResultSetClassName();
473
        $resultSet = GeneralUtility::makeInstance($resultSetClass);
474
        $resultSet->setUsedSearchRequest($searchRequest);
475
        $this->lastResultSet = $resultSet;
476 2
477
        $resultSet = $this->handleSearchHook('beforeSearch', $resultSet);
478
479
        if ($searchRequest->getRawUserQueryIsNull() && !$this->getInitialSearchIsConfigured()) {
480 2
            // when no rawQuery was passed or no initialSearch is configured, we pass an empty result set
481
            return $resultSet;
482
        }
483
484
        if ($searchRequest->getRawUserQueryIsEmptyString() && !$this->typoScriptConfiguration->getSearchQueryAllowEmptyQuery()) {
485
            // the user entered an empty query string "" or "  " and empty querystring is not allowed
486
            return $resultSet;
487 36
        }
488
489
        $rawQuery = $searchRequest->getRawUserQuery();
490 36
        $resultsPerPage = $this->getNumberOfResultsPerPage($rawQuery, $searchRequest->getResultsPerPage());
0 ignored issues
show
Documentation introduced by
$rawQuery is of type array|null, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
Bug introduced by
It seems like $searchRequest->getResultsPerPage() targeting ApacheSolrForTypo3\Solr\...st::getResultsPerPage() can also be of type array; however, ApacheSolrForTypo3\Solr\...umberOfResultsPerPage() does only seem to accept integer|null, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
491 2
        $query = $this->getPreparedQuery($rawQuery, $resultsPerPage);
0 ignored issues
show
Documentation introduced by
$rawQuery is of type array|null, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
492
493
        $resultSet->setUsedQuery($query);
494 36
495 36
        $currentPage = max(0, $searchRequest->getPage());
496 33
        // if the number of results per page has been changed by the current request, reset the pagebrowser
497
        if ($this->resultsPerPageChanged) {
498
            $currentPage = 0;
499 3
        }
500
501
        $offSet = $currentPage * $resultsPerPage;
502 3
        // performing the actual search, sending the query to the Solr server
503
        $response = $this->search->search($query, $offSet, null);
504 3
505
        $this->processResponse($rawQuery, $query, $response);
0 ignored issues
show
Documentation introduced by
$rawQuery is of type array|null, but the function expects a string.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
506
        $this->addSearchResultsToResultSet($response, $resultSet);
507
508 3
        $resultSet->setResponse($response);
509 3
        $resultSet->setUsedPage($currentPage);
510
        $resultSet->setUsedResultsPerPage($resultsPerPage);
511
        $resultSet->setUsedAdditionalFilters($this->getAdditionalFilters());
512
        $resultSet->setUsedSearch($this->search);
513 3
514 3
        /** @var $searchResultReconstitutionProcessor ResultSetReconstitutionProcessor */
515
        $searchResultReconstitutionProcessor = GeneralUtility::makeInstance(ResultSetReconstitutionProcessor::class);
516
        $searchResultReconstitutionProcessor->process($resultSet);
517
518 3
        return $this->handleSearchHook('afterSearch', $resultSet);
519
    }
520
521 3
    /**
522
     * Retrieves a single document from solr by document id.
523
     *
524
     * @param string $documentId
525
     * @return SearchResult
526
     */
527
    public function getDocumentById($documentId)
528
    {
529
        /* @var $query Query */
530 34
        $query = GeneralUtility::makeInstance(Query::class, $documentId);
531
        $query->setQueryFieldsFromString('id');
532
533 34
        $response = $this->search->search($query, 0, 1);
534 34
        $this->processResponse($documentId, $query, $response);
535 34
536 34
        $resultDocument = isset($response->response->docs[0]) ? $response->response->docs[0] : null;
0 ignored issues
show
Bug introduced by
The property response does not seem to exist. Did you mean _response?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
537
        return $resultDocument;
538 34
    }
539
540 34
    /**
541
     * This method is used to call the registered hooks during the search execution.
542 1
     *
543
     * @param string $eventName
544
     * @param SearchResultSet $resultSet
545 33
     * @return SearchResultSet
546
     */
547 2
    private function handleSearchHook($eventName, SearchResultSet $resultSet)
548
    {
549
        if (!is_array($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr'][$eventName])) {
550 31
            return $resultSet;
551 31
        }
552 31
553
        foreach ($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['solr'][$eventName] as $classReference) {
554 31
            $afterSearchProcessor = GeneralUtility::getUserObj($classReference);
555
            if ($afterSearchProcessor instanceof SearchResultSetProcessor) {
556 31
                $afterSearchProcessor->process($resultSet);
557
            }
558 31
        }
559 1
560
        return $resultSet;
561
    }
562 31
563
    /**
564 31
     * @return SearchResultSet
565
     */
566 31
    public function getLastResultSet()
567 31
    {
568
        return $this->lastResultSet;
569 31
    }
570 31
571 31
    /**
572 31
     * This method returns true when the last search was executed with an empty query
573 31
     * string or whitespaces only. When no search was triggered it will return false.
574
     *
575 31
     * @return bool
576
     */
577
    public function getLastSearchWasExecutedWithEmptyQueryString()
578
    {
579
        $wasEmptyQueryString = false;
580
        if ($this->lastResultSet != null) {
581
            $wasEmptyQueryString = $this->lastResultSet->getUsedSearchRequest()->getRawUserQueryIsEmptyString();
582
        }
583
584 1
        return $wasEmptyQueryString;
585
    }
586
587 1
    /**
588 1
     * @param int $requestedPerPage
589
     */
590 1
    protected function setPerPageInSession($requestedPerPage)
591 1
    {
592
        $GLOBALS['TSFE']->fe_user->setKey('ses', 'tx_solr_resultsPerPage', intval($requestedPerPage));
593 1
    }
594 1
595
    /**
596
     * @return mixed
597
     */
598
    protected function getPerPageFromSession()
599
    {
600
        return $GLOBALS['TSFE']->fe_user->getKey('ses', 'tx_solr_resultsPerPage');
601
    }
602
603
    /**
604 34
     * @return bool
605
     */
606 34
    protected function getInitialSearchIsConfigured()
607 34
    {
608
        return $this->typoScriptConfiguration->getSearchInitializeWithEmptyQuery() || $this->typoScriptConfiguration->getSearchShowResultsOfInitialEmptyQuery() || $this->typoScriptConfiguration->getSearchInitializeWithQuery() || $this->typoScriptConfiguration->getSearchShowResultsOfInitialQuery();
609
    }
610
611
    /**
612
     * @return mixed
613
     */
614
    protected function getRegisteredSearchComponents()
615
    {
616
        return GeneralUtility::makeInstance(SearchComponentManager::class)->getSearchComponents();
617
    }
618
619
    /**
620
     * This method is used to reference the SearchResult object from the response in the SearchResultSet object.
621
     *
622
     * @param \Apache_Solr_Response $response
623 19
     * @param SearchResultSet $resultSet
624
     */
625 19
    protected function addSearchResultsToResultSet($response, $resultSet)
626
    {
627
        if (!is_array($response->response->docs)) {
0 ignored issues
show
Bug introduced by
The property response does not seem to exist. Did you mean _response?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
628
            return;
629
        }
630
631
        foreach ($response->response->docs as $searchResult) {
0 ignored issues
show
Bug introduced by
The property response does not seem to exist. Did you mean _response?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
632
            $resultSet->addSearchResult($searchResult);
633
        }
634 25
    }
635
}
636