Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 59
0.00% covered (danger)
0.00%
0 / 6
CRAP
0.00% covered (danger)
0.00%
0 / 1
EntityResultType
0.00% covered (danger)
0.00%
0 / 59
0.00% covered (danger)
0.00%
0 / 6
72
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getSourceFiltering
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
6
 getFields
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getHighlightingConfiguration
0.00% covered (danger)
0.00%
0 / 47
0.00% covered (danger)
0.00%
0 / 1
6
 transformElasticsearchResult
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 createEmptyResult
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2namespace Wikibase\Search\Elastic;
3
4use CirrusSearch\Search\BaseCirrusSearchResultSet;
5use CirrusSearch\Search\BaseResultsType;
6use CirrusSearch\Searcher;
7use Wikibase\Lib\TermLanguageFallbackChain;
8
9/**
10 * Result class for fulltext search of entities.
11 */
12class EntityResultType extends BaseResultsType {
13
14    /**
15     * @param string $displayLanguage Display Language code
16     * @param TermLanguageFallbackChain $termFallbackChain Fallback chain for display
17     */
18    public function __construct(
19        private readonly string $displayLanguage,
20        private readonly TermLanguageFallbackChain $termFallbackChain,
21    ) {
22    }
23
24    /**
25     * Get the source filtering to be used loading the result.
26     *
27     * @return false|string|array corresponding to Elasticsearch source filtering syntax
28     */
29    public function getSourceFiltering() {
30        $fields = parent::getSourceFiltering();
31        $fields[] = 'timestamp';
32        $fields[] = 'sitelink_count';
33        $fields[] = 'statement_count';
34        foreach ( $this->termFallbackChain->getFetchLanguageCodes() as $code ) {
35            $fields[] = "labels.$code";
36            $fields[] = "descriptions.$code";
37        }
38        return $fields;
39    }
40
41    /**
42     * Get the fields to load.  Most of the time we'll use source filtering instead but
43     * some fields aren't part of the source.
44     *
45     * @return array corresponding to Elasticsearch fields syntax
46     */
47    public function getFields() {
48        return [];
49    }
50
51    /**
52     * Get the highlighting configuration.
53     *
54     * @param array $highlightSource configuration for how to highlight the source.
55     *  Empty if source should be ignored.
56     * @return array|null highlighting configuration for elasticsearch
57     */
58    public function getHighlightingConfiguration( array $highlightSource ) {
59        $config = [
60            'pre_tags' => [ Searcher::HIGHLIGHT_PRE_MARKER ],
61            'post_tags' => [ Searcher::HIGHLIGHT_POST_MARKER ],
62            'fields' => [],
63        ];
64
65        $config['fields']['title'] = [
66            'type' => 'experimental',
67            'fragmenter' => "none",
68            'number_of_fragments' => 0,
69            'matched_fields' => [ 'title.keyword' ]
70        ];
71
72        foreach ( $this->termFallbackChain->getFetchLanguageCodes() as $code ) {
73            $config['fields']["labels.{$code}.plain"] = [
74                'type' => 'experimental',
75                'fragmenter' => "none",
76                'number_of_fragments' => 0,
77                'options' => [
78                    'skip_if_last_matched' => true,
79                    'return_snippets_and_offsets' => true
80                ],
81            ];
82            $config['fields']["descriptions.{$code}.plain"] = [
83                'type' => 'experimental',
84                'fragmenter' => "none",
85                'number_of_fragments' => 0,
86                'options' => [
87                    'skip_if_last_matched' => true,
88                ],
89            ];
90        }
91
92        $config['fields']["labels.*.plain"] = [
93            'type' => 'experimental',
94            'fragmenter' => "none",
95            'number_of_fragments' => 0,
96            'options' => [
97                'skip_if_last_matched' => true,
98                'return_snippets_and_offsets' => true
99            ],
100        ];
101        $config['fields']["descriptions.*.plain"] = [
102            'type' => 'experimental',
103            'fragmenter' => "none",
104            'number_of_fragments' => 0,
105            'options' => [
106                'skip_if_last_matched' => true,
107            ],
108        ];
109
110        return $config;
111    }
112
113    /**
114     * @param \Elastica\ResultSet $result
115     * @return mixed Set of search results, the types of which vary by implementation.
116     */
117    public function transformElasticsearchResult( \Elastica\ResultSet $result ) {
118        return new EntityResultSet( $this->displayLanguage, $this->termFallbackChain, $result );
119    }
120
121    /**
122     * @return mixed Empty set of search results
123     */
124    public function createEmptyResult() {
125        return BaseCirrusSearchResultSet::emptyResultSet( false );
126    }
127
128}