SearchService::getLegacyKernel()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
c 0
b 0
f 0
rs 10
cc 1
nc 1
nop 0
1
<?php
2
3
namespace Kaliop\EzFindSearchEngineBundle\Core\Repository;
4
5
use Closure;
6
use ezfSearchResultInfo;
7
use Psr\Log\LoggerInterface;
8
use eZ\Publish\API\Repository\Values\Content\Search\Facet;
9
use eZ\Publish\API\Repository\SearchService as SearchServiceInterface;
10
use eZ\Publish\API\Repository\ContentService;
11
use eZ\Publish\API\Repository\ContentTypeService;
12
use eZ\Publish\API\Repository\Values\Content\LocationQuery;
13
use eZ\Publish\API\Repository\Values\Content\Query;
14
use eZ\Publish\API\Repository\Values\Content\Query\Criterion;
15
use eZ\Publish\API\Repository\Exceptions\NotFoundException;
16
use eZ\Publish\API\Repository\Exceptions\UnauthorizedException;
17
use eZ\Publish\Core\Base\Exceptions\NotFoundException as CoreNotFoundException;
18
use eZ\Publish\Core\Base\Exceptions\InvalidArgumentException;
19
use Kaliop\EzFindSearchEngineBundle\API\Repository\Values\Content\Query as KaliopQuery;
20
use Kaliop\EzFindSearchEngineBundle\API\Repository\Values\Search\SearchResult as KaliopSearchResult;
21
use Kaliop\EzFindSearchEngineBundle\API\Repository\Values\Search\SearchHit;
22
use Kaliop\EzFindSearchEngineBundle\Core\Base\Exceptions\NotImplementedException;
23
use Kaliop\EzFindSearchEngineBundle\Core\Persistence\eZFind\Content\Search\Common\Gateway\CriteriaConverter;
24
use Kaliop\EzFindSearchEngineBundle\Core\Persistence\eZFind\Content\Search\Common\Gateway\SortClauseConverter;
25
use Kaliop\EzFindSearchEngineBundle\Core\Base\Exceptions\eZFindException;
26
use Kaliop\EzFindSearchEngineBundle\Core\Persistence\eZFind\Content\Search\Common\Gateway\FacetConverter;
27
use Kaliop\EzFindSearchEngineBundle\DataCollector\Logger\QueryLogger;
28
29
/// @todo implement LoggerTrait or similar interface
30
class SearchService implements SearchServiceInterface
31
{
32
    const DEFAULT_LIMIT = 20;
33
34
    const FETCH_ALL = 2147483647; // Max 32-bit signed Integer (limited by SOLR)
35
36
    protected $ezFindModule;
37
38
    protected $ezFindFunction;
39
40
    /** @var Closure */
41
    protected $legacyKernelClosure;
42
43
    /** @var ContentService */
44
    protected $contentService;
45
46
    /** @var ContentTypeService */
47
    protected $contentTypeService;
48
49
    /** @var CriteriaConverter */
50
    protected $filterCriteriaConverter;
51
52
    /** @var  FacetConverter */
53
    protected $facetConverter;
54
55
    /** @var SortClauseConverter */
56
    protected $sortClauseConverter;
57
58
    protected $defaultBoostFunctions;
59
60
    protected $defaultFieldsToReturn;
61
62
    protected $defaultReturnType;
63
64
    protected $defaultQueryHandler = 'ezpublish';
65
66
    protected $defaultEnableElevation = true;
67
68
    protected $defaultForceElevation = false;
69
70
    /** @var bool */
71
    protected $throwErrors;
72
73
    /** @var LoggerInterface */
74
    protected $logger;
75
76
    /** @var QueryLogger */
77
    protected $queryLogger;
78
79
    public function __construct(
80
        Closure $legacyKernelClosure,
81
        ContentService $contentService,
82
        ContentTypeService $contentTypeService,
83
        CriteriaConverter $filterCriteriaConverter,
84
        FacetConverter $facetConverter,
85
        SortClauseConverter $sortClauseConverter,
86
        $defaultBoostFunctions,
87
        $defaultFieldsToReturn,
88
        $defaultReturnType = KaliopQuery::RETURN_CONTENTS,
89
        $ezFindModule = 'ezfind',
90
        $ezFindFunction = 'search',
91
        $throwErrors = true,
92
        LoggerInterface $logger = null,
93
        QueryLogger $queryLogger = null
94
    ) {
95
        $this->legacyKernelClosure = $legacyKernelClosure;
96
        $this->contentService = $contentService;
97
        $this->contentTypeService = $contentTypeService;
98
        $this->defaultReturnType = $defaultReturnType;
99
        $this->ezFindModule = $ezFindModule;
100
        $this->ezFindFunction = $ezFindFunction;
101
        $this->throwErrors = $throwErrors;
102
        $this->logger = $logger;
103
        $this->queryLogger = $queryLogger;
104
105
        // Converters
106
        $this->filterCriteriaConverter = $filterCriteriaConverter;
107
        $this->facetConverter = $facetConverter;
108
        $this->sortClauseConverter = $sortClauseConverter;
109
110
        // Making sure these are arrays
111
        $this->defaultBoostFunctions = (array)$defaultBoostFunctions;
112
        $this->defaultFieldsToReturn = (array)$defaultFieldsToReturn;
113
    }
114
115
    /**
116
     * @todo fill in the remaining members: timedOut, spellSuggestion
117
     *
118
     * @inheritdoc
119
     */
120
    public function findContent(Query $query, array $fieldFilters = [], $filterOnUserPermissions = true)
121
    {
122
        $result = $this->performSearch($query, $fieldFilters, $filterOnUserPermissions);
123
124
        $maxScore = null;
125
        $time = null;
126
127
        // q: is there any case where SearchExtras is not set or of a different type?
128
        if (isset($result['SearchExtras']) && $result['SearchExtras'] instanceof ezfSearchResultInfo) {
129
            /** @var ezfSearchResultInfo $extras */
130
            $extras = $result['SearchExtras'];
131
            $responseHeader = $extras->attribute('responseHeader');
132
            $time = $responseHeader['QTime'];
133
134
            // trick to access data from a protected member of ezfSearchResultInfo
135
            // @see http://blag.kazeno.net/development/access-private-protected-properties
136
            $propGetter = Closure::bind(function($prop){return $this->$prop;}, $extras, $extras);
137
            $resultArray = $propGetter('ResultArray');
138
139
            if (isset($resultArray['response']['maxScore'])) {
140
                $maxScore = $resultArray['response']['maxScore'];
141
            }
142
143
            // optimize: remove from SearchExtras 'response' to save memory using the 'Closure::bind' hack
144
            /// @todo (!important) make the cutover limit configurable
145
            if ($result['SearchCount'] > 100) {
146
                $resultsCleaner = Closure::bind(function(){unset($this->ResultArray['response']['docs']);}, $extras, $extras);
147
                $resultsCleaner();
148
            }
149
        }
150
151
        return new KaliopSearchResult(
152
            [
153
                'facets' => $result['Facets'],
154
                'searchHits' => $result['SearchHits'],
155
                'time' => $time,
156
                'maxScore' => $maxScore,
157
                'totalCount' => $result['SearchCount'],
158
                'searchExtras' => $result['SearchExtras'],
159
            ]
160
        );
161
    }
162
163
    /**
164
     * @todo Implement this method shrinking the fieldstoreturn to the bare minimum needed to build contentInfo
165
     *       without having to query the database
166
     * @since 5.4.5
167
     */
168
    public function findContentInfo(Query $query, array $languageFilter = [], $filterOnUserPermissions = true)
0 ignored issues
show
Unused Code introduced by
The parameter $query is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $languageFilter is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $filterOnUserPermissions is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
169
    {
170
        throw new NotImplementedException('Intentionally not implemented');
171
    }
172
173
    /**
174
     * @todo disable asking the total count for speed if possible
175
     *
176
     * @inheritdoc
177
     */
178
    public function findSingle(Criterion $criterion, array $fieldFilters = [], $filterOnUserPermissions = true)
179
    {
180
        $query = new Query();
181
        $query->criterion = $criterion;
182
        $query->limit = 1;
183
        $query->offset = 0;
184
185
        $result = $this->performSearch($query, $fieldFilters, $filterOnUserPermissions, true);
0 ignored issues
show
Documentation introduced by
true is of type boolean, but the function expects a null|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...
186
187
        if (!$result['SearchCount']) {
188
            throw new CoreNotFoundException('Content', 'findSingle() found no content for given criterion');
189
        } else {
190
            if ($result['SearchCount'] > 1) {
191
                throw new InvalidArgumentException(
192
                    'totalCount',
193
                    'findSingle() found more then one item for given criterion'
194
                );
195
            }
196
        }
197
198
        return reset($result['SearchHits']);
199
    }
200
201
    public function suggest($prefix, $fieldPaths = [], $limit = 10, Criterion $filter = null)
202
    {
203
        throw new NotImplementedException('Intentionally not implemented');
204
    }
205
206
    public function findLocations(LocationQuery $query, $languageFilter = [], $filterOnUserPermissions = true)
207
    {
208
        throw new NotImplementedException('Intentionally not implemented');
209
    }
210
211
    /**
212
     * @return \ezpKernel
213
     */
214
    protected function getLegacyKernel()
215
    {
216
        $legacyKernelClosure = $this->legacyKernelClosure;
217
218
        return $legacyKernelClosure();
219
    }
220
221
    /**
222
     * Perform SOLR search query.
223
     *
224
     * @param Query $query
225
     * @param array $fieldFilters
226
     * @param bool $filterOnUserPermissions
227
     * @param null|string $forceReturnType  When set, it overrides both the service default and the query default
228
     *
229
     * @return array    The same as returned by \eZSolr::Search(), with added members SearchHits and Facets
230
     *
231
     * @throws eZFindException
232
     */
233
    protected function performSearch(
234
        Query $query,
235
        array $fieldFilters,
236
        $filterOnUserPermissions,
237
        $forceReturnType = null
238
    ) {
239
        $returnType = $this->getReturnType($query, $forceReturnType);
240
241
        $this->initializeQueryLimit($query);
242
243
        $searchParameters = $this->getLegacySearchParameters($query, $fieldFilters, $filterOnUserPermissions, $returnType);
244
//var_dump($searchParameters);
245
        /** @var array $searchResult */
246
        $searchResult = $this->getLegacyKernel()->runCallback(
247
            function () use ($searchParameters) {
248
                return \eZFunctionHandler::execute($this->ezFindModule, $this->ezFindFunction, $searchParameters);
249
            },
250
            false
251
        );
252
253
        if ($this->queryLogger) {
254
            $this->queryLogger->addResultsInfo($searchResult['SearchExtras']);
255
        }
256
257
        $this->logSearchErrors($searchResult);
258
259
        if ($this->throwErrors) {
260
            $this->throwIfSearchError($searchResult);
261
        }
262
263
        $searchResult['SearchHits'] = $this->buildResultObjects($searchResult, $returnType);
264
        $searchResult['Facets'] = $this->buildResultFacets($searchResult['SearchExtras'], $query->facetBuilders);
265
266
        return $searchResult;
267
    }
268
269
    /**
270
     * Initializes the query limit to ensure it is set.
271
     *
272
     * @param Query $query
273
     */
274
    protected function initializeQueryLimit(Query $query)
275
    {
276
        if ($query->limit < 0) {
277
            $query->limit = self::FETCH_ALL;
278
        } elseif ($query->limit === null) {
279
            $query->limit = self::DEFAULT_LIMIT;
280
        }
281
    }
282
283
    /**
284
     * @see \Solr::search
285
     * @see ezfind/modules/ezfind/function_definition.php
286
     * @todo should we handle $fieldFilters ?
287
     *
288
     * @param Query $query
289
     * @param array $fieldFilters
290
     * @param bool $filterOnUserPermissions
291
     * @param string $returnType
292
     * @return array
293
     */
294
    protected function getLegacySearchParameters(Query $query, array $fieldFilters, $filterOnUserPermissions, $returnType)
0 ignored issues
show
Unused Code introduced by
The parameter $fieldFilters is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
295
    {
296
        $searchParameters = [
297
            'offset' => $query->offset,
298
            'limit' => $query->limit,
299
            // When we are rebuilding eZ5 objects, no need to load custom fields from Solr.
300
            // This 'hack' is the way to get ezfind to generate the minimum field list, plus the score
301
            'fields_to_return' => $returnType == KaliopQuery::RETURN_CONTENTS ? array('meta_score_value:score') : $this->extractLegacyParameter('fields_to_return', $query),
302
            // we either load eZ5 objects or return solr data, no need to tell ez4 to load objects as well
303
            'as_objects' => false, //$this->extractLegacyParameter('as_objects', $query),
304
            'query_handler' => $this->extractLegacyParameter('query_handler', $query),
305
            'enable_elevation' => $this->extractLegacyParameter('enable_elevation', $query),
306
            'force_elevation' => $this->extractLegacyParameter('force_elevation', $query),
307
            'boost_functions' => $this->extractLegacyParameter('boost_functions', $query),
308
        ];
309
310
        $scoreSort = false;
311
        if ($query->sortClauses) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $query->sortClauses of type eZ\Publish\API\Repositor...tent\Query\SortClause[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
312
            $searchParameters['sort_by'] = $this->extractSort($query->sortClauses);
313
314
            if (array_key_exists('score', $searchParameters['sort_by'])) {
315
                $scoreSort = true;
316
            }
317
        }
318
//var_dump($query->criterion);die();
319
        $criterionFilter = array();
320
        if ($query->criterion) {
321
            $criterionFilter = $this->extractFilter($query->criterion);
322
        }
323
324
        $filterFilter = array();
325
        if ($query->filter) {
326
            $filterFilter = $this->extractFilter($query->filter);
327
        }
328
329
        if ($query->facetBuilders) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $query->facetBuilders of type eZ\Publish\API\Repositor...nt\Query\FacetBuilder[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
330
            $searchParameters['facet'] = $this->extractFacet($query->facetBuilders);
331
        }
332
333
        if ($this->isEzFindCriterion($query->criterion)) {
334
            $searchParameters['query'] = reset($criterionFilter);
335
            $searchParameters['filter'] = $filterFilter;
336
        } elseif ($scoreSort) {
337
            // since we are sorting by score, we need to generate the solr query, as that is what is used to calculate score
338
            $searchParameters['query'] = $this->filterCriteriaConverter->generateQueryString($criterionFilter);
339
            $searchParameters['filter'] = $filterFilter;
340
        } else {
341
            // since we are not sorting by score, no need to do complex stuff. Only use a solr filter, which should be faster
342
            $searchParameters['query'] = '';
343
            $searchParameters['filter'] = array_merge($criterionFilter, $filterFilter);
344
        }
345
346
        // If we need to filter on permissions, set this to null so eZFind will fill it in.
347
        // Otherwise an empty array prevents eZFind from applying limitations
348
        if ($filterOnUserPermissions) {
349
            $searchParameters['limitation'] = null;
350
        } else {
351
            $searchParameters['limitation'] = [];
352
        }
353
354
        return $searchParameters;
355
    }
356
357
    protected function extractLegacyParameter($paramName, Query $query)
358
    {
359
        switch ($paramName) {
360
            case 'boost_functions':
361
                return ($query instanceof KaliopQuery && is_array(
362
                        $query->boostFunctions
363
                    )) ? $query->boostFunctions : $this->defaultBoostFunctions;
364
            case 'enable_elevation':
365
                return ($query instanceof KaliopQuery) ? $query->enableElevation : $this->defaultEnableElevation;
366
            case 'fields_to_return':
367
                return ($query instanceof KaliopQuery && is_array(
368
                        $query->fieldsToReturn
369
                    )) ? $query->fieldsToReturn : $this->defaultFieldsToReturn;
370
            case 'force_elevation':
371
                return ($query instanceof KaliopQuery) ? $query->forceElevation : $this->defaultForceElevation;
372
            case 'query_handler':
373
                return ($query instanceof KaliopQuery) ? $query->queryHandler : $this->defaultQueryHandler;
374
        }
375
    }
376
377
    /**
378
     * Order of importance:
379
     * 1. override (function parameter)
380
     * 2. query member (if set)
381
     * 3. default for this service
382
     * @param Query $query
383
     * @param null|string $forceReturnType
384
     * @return string
385
     */
386
    protected function getReturnType(Query $query, $forceReturnType = null)
387
    {
388
        if ($forceReturnType !== null) {
389
            return $forceReturnType;
390
        }
391
392
        return ($query instanceof KaliopQuery && $query->returnType !== null) ? $query->returnType : $this->defaultReturnType;
393
    }
394
395
    /**
396
     * Returns true if there is a single search criterion of type EzFindText
397
     * @param Query\Criterion|Query\Criterion[] $criteria $criteria
398
     * @return bool
399
     */
400
    protected function isEzFindCriterion($criteria)
401
    {
402
        if (!is_array($criteria)) {
403
            $criteria = array($criteria);
404
        }
405
406
        return (count($criteria) == 1 && $criteria[0] instanceof KaliopQuery\Criterion\EzFindText);
407
    }
408
409
    /**
410
     * @param Query\Criterion|Query\Criterion[] $criteria
411
     * @return array
412
     * @throws NotImplementedException
413
     */
414
    protected function extractFilter($criteria)
415
    {
416
        if (!is_array($criteria)) {
417
            $criteria = array($criteria);
418
        }
419
420
        $result = [];
421
422
        foreach ($criteria as $criterion) {
423
            $result[] = $this->filterCriteriaConverter->handle($criterion);
424
        }
425
426
        return $result;
427
    }
428
429
    /**
430
     * Extract FacetBuilders into legacy eZFind facet array.
431
     *
432
     * @param Query\FacetBuilder[] $facetBuilders
433
     * @return array
434
     *
435
     * @throws NotImplementedException
436
     */
437
    protected function extractFacet($facetBuilders)
438
    {
439
        $facets = [];
440
441
        foreach ($facetBuilders as $facetBuilder) {
442
            $facets[] = $this->facetConverter->handle($facetBuilder);
443
        }
444
445
        return $facets;
446
    }
447
448
    protected function extractSort($sortClauses)
449
    {
450
        $result = [];
451
452
        foreach ($sortClauses as $clause) {
453
            $sortClause = $this->sortClauseConverter->handle($clause);
454
            if (!empty($sortClause)) {
455
                $result = array_merge($result, $sortClause);
456
            }
457
        }
458
459
        return $result;
460
    }
461
462
    protected function throwIfSearchError($searchResult)
463
    {
464
        if (!is_array($searchResult)) {
465
            throw new eZFindException('The legacy search result is not an array');
466
        }
467
//var_dump($searchResult);die();
468
        if (isset($searchResult['SearchExtras']) && $searchResult['SearchExtras'] instanceof ezfSearchResultInfo) {
469
            $errors = $searchResult['SearchExtras']->attribute('error');
470
            /// @todo what if $errors it is an empty string, an array with unexepcted members or not even an array ?
471
            if (is_string($errors)) {
472
                throw new eZFindException($errors);
473
            } elseif (is_array($errors) && isset($errors['msg']) && isset($errors['code'])) {
474
                throw new eZFindException($errors['msg'], $errors['code']);
475
            }
476
        }
477
    }
478
479
    protected function logSearchErrors($searchResult)
480
    {
481
        if (!is_array($searchResult)) {
482
            if ($this->logger) {
483
                $this->logger->error('The legacy search result is not an array');
484
            }
485
486
            return;
487
        }
488
489
        /// @todo allow the query not to return some of these
490
        if (!isset($searchResult['SearchResult']) || !isset($searchResult['SearchCount']) || !isset($searchResult['StopWordArray']) ||
491
            !isset($searchResult['SearchExtras']) || !($searchResult['SearchExtras'] instanceof ezfSearchResultInfo)
492
        ) {
493
            if ($this->logger) {
494
                $this->logger->error('The legacy search result array misses expected members');
495
            }
496
497
            return;
498
        }
499
500
        /** @var ezfSearchResultInfo $searchExtras */
501
        $searchExtras = $searchResult['SearchExtras'];
502
        $errors = $searchExtras->attribute('error');
503
        if (!empty($errors) && $this->logger) {
504
            $this->logger->error(print_r($errors, true));
505
        }
506
    }
507
508
    /**
509
     * @param array $searchResultsContainer
510
     * @param string $returnType
511
     * @return SearchHit[]|array depending on $returnObjects
512
     */
513
    protected function buildResultObjects($searchResultsContainer, $returnType)
514
    {
515
        if ($returnType == KaliopQuery::RETURN_CONTENTS || $returnType == KaliopQuery::RETURN_EZFIND_DATA) {
516
            $searchResults = $searchResultsContainer['SearchResult'];
517
        } else {
518
            // we need a little hack to be able to access data in protected members
519
            $extras = $searchResultsContainer['SearchExtras'];
520
521
            // trick to access data from a protected member of ezfSearchResultInfo
522
            // @see http://blag.kazeno.net/development/access-private-protected-properties
523
            $propGetter = Closure::bind(function($prop){return $this->$prop;}, $extras, $extras);
524
            $resultArray = $propGetter('ResultArray');
525
            $searchResults = $resultArray['response']['docs'];
526
        }
527
528
        if (!is_array($searchResults)) {
529
            return [];
530
        }
531
532
        $results = array();
533
534
        foreach ($searchResults as $index => $result) {
535
            switch($returnType) {
536
537
                case KaliopQuery::RETURN_CONTENTS:
538
                    try {
539
                        $results[$index] = new SearchHit(
540
                            [
541
                                'valueObject' => $this->contentService->loadContent($result['id']),
542
                                'score' => isset($result['score'])? $result['score'] : null,
543
                                'highlight' => isset($result['highlight'])? $result['highlight'] : null,
544
                                'elevated' => isset($result['elevated'])? $result['elevated'] : null,
545
                                /// @todo decide what is the correct value for 'index': guid, installation_id/guid ?
546
                                //'index' => isset($result['guid'])? $result['guid'] : null,
547
                            ]
548
                        );
549
                    } catch (NotFoundException $e) {
550 View Code Duplication
                        if ($this->logger) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
551
                            // Solr sometimes gets out of sync... make sure users don't see exceptions here
552
                            $message = sprintf(
553
                                "Can not access content corresponding to solr record with Content Id: %s, Main Location Id: %s\n%s\n%s",
554
                                $result['id'],
555
                                $result['main_node_id'],
556
                                $e->getMessage(),
557
                                $e->getTraceAsString()
558
                            );
559
560
                            $this->logger->warning($message);
561
                        }
562
                        unset($searchResults[$index]);
563
                    } catch (UnauthorizedException $e) {
564
                        /// @todo verify when/if this can happen...
565 View Code Duplication
                        if ($this->logger) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
566
                            $message = sprintf(
567
                                "Can not access content corresponding to solr record with Content Id: %s, Main Location Id: %s\n%s\n%s",
568
                                $result['id'],
569
                                $result['main_node_id'],
570
                                $e->getMessage(),
571
                                $e->getTraceAsString()
572
                            );
573
574
                            $this->logger->warning($message);
575
                        }
576
                        unset($searchResults[$index]);
577
                    }
578
                    break;
579
580
                case KaliopQuery::RETURN_EZFIND_DATA:
581
                case KaliopQuery::RETURN_SOLR_DATA:
582
                    $results[$index] = new SearchHit(
583
                        [
584
                            'valueObject' => $result,
585
                            'score' => isset($result['score'])? $result['score'] : null,
586
                            'highlight' => isset($result['highlight'])? $result['highlight'] : null,
587
                            'elevated' => isset($result['elevated'])? $result['elevated'] : null,
588
                            /// @todo decide what is the correct value for 'index': guid, installation_id/guid ?
589
                            //'index' => isset($result['guid'])? $result['guid'] : null,
590
                        ]
591
                    );
592
                    break;
593
            }
594
        }
595
596
        return $results;
597
    }
598
599
    /**
600
     * Create result facets based on SOLR returned results.
601
     *
602
     * @param ezfSearchResultInfo $searchResultInfo
603
     * @param Query\FacetBuilder[] $facetBuilders
604
     *
605
     * @return Facet[]
606
     */
607
    protected function buildResultFacets(ezfSearchResultInfo $searchResultInfo, $facetBuilders)
608
    {
609
        $facets = [];
610
611
        foreach ($facetBuilders as $facetBuilder) {
612
            $facets[] = $this->facetConverter->buildFacet(
613
                $facetBuilder,
614
                $searchResultInfo->attribute('facet_fields'),
615
                $searchResultInfo->attribute('facet_queries'),
616
                $searchResultInfo->attribute('facet_dates'),
617
                $searchResultInfo->attribute('facet_ranges')
618
            );
619
        }
620
621
        return $facets;
622
    }
623
}
624