Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 39 |
|
0.00% |
0 / 3 |
CRAP | |
0.00% |
0 / 1 |
FieldIterator | |
0.00% |
0 / 39 |
|
0.00% |
0 / 3 |
182 | |
0.00% |
0 / 1 |
__construct | |
0.00% |
0 / 12 |
|
0.00% |
0 / 1 |
2 | |||
getLanguageAgnosticQueries | |
0.00% |
0 / 7 |
|
0.00% |
0 / 1 |
20 | |||
getLanguageAwareQueries | |
0.00% |
0 / 20 |
|
0.00% |
0 / 1 |
72 |
1 | <?php |
2 | |
3 | namespace Wikibase\MediaInfo\Search\ASTQueryBuilder; |
4 | |
5 | use ArrayIterator; |
6 | |
7 | class FieldIterator extends ArrayIterator { |
8 | public const LANGUAGE_AWARE_FIELDS = [ |
9 | 'descriptions.$language', |
10 | 'descriptions.$language.plain', |
11 | ]; |
12 | |
13 | public const LANGUAGE_AGNOSTIC_FIELDS = [ |
14 | 'title', |
15 | 'title.plain', |
16 | 'category', |
17 | 'category.plain', |
18 | 'redirect.title', |
19 | 'redirect.title.plain', |
20 | 'heading', |
21 | 'heading.plain', |
22 | 'auxiliary_text', |
23 | 'auxiliary_text.plain', |
24 | 'text', |
25 | 'text.plain', |
26 | 'file_text', |
27 | 'file_text.plain', |
28 | 'suggest', |
29 | ]; |
30 | |
31 | public const STEMMED_TO_PLAIN_FIELDS_MAP = [ |
32 | 'descriptions.$language' => 'descriptions.$language.plain', |
33 | 'title' => 'title.plain', |
34 | 'category' => 'category.plain', |
35 | 'redirect.title' => 'redirect.title.plain', |
36 | 'heading' => 'heading.plain', |
37 | 'auxiliary_text' => 'auxiliary_text.plain', |
38 | 'text' => 'text.plain', |
39 | 'file_text' => 'file_text.plain', |
40 | ]; |
41 | |
42 | public const STEMMED_FIELDS = [ |
43 | 'descriptions.$language', |
44 | 'title', |
45 | 'category', |
46 | 'redirect.title', |
47 | 'heading', |
48 | 'auxiliary_text', |
49 | 'text', |
50 | 'file_text', |
51 | ]; |
52 | |
53 | public const PLAIN_FIELDS = [ |
54 | 'descriptions.$language.plain', |
55 | 'title.plain', |
56 | 'category.plain', |
57 | 'redirect.title.plain', |
58 | 'heading.plain', |
59 | 'auxiliary_text.plain', |
60 | 'text.plain', |
61 | 'file_text.plain', |
62 | 'suggest', |
63 | ]; |
64 | |
65 | /** @var fieldQueryBuilderInterface */ |
66 | private $fieldQueryBuilder; |
67 | |
68 | /** @var string[] */ |
69 | private $fields; |
70 | |
71 | /** @var string[] */ |
72 | private $languages; |
73 | |
74 | /** @var array[] */ |
75 | private $stemmingSettings; |
76 | |
77 | /** @var float[] */ |
78 | private $boosts; |
79 | |
80 | /** @var float[] */ |
81 | private $decays; |
82 | |
83 | public function __construct( |
84 | fieldQueryBuilderInterface $fieldQueryBuilder, |
85 | array $fields, |
86 | array $languages, |
87 | array $stemmingSettings, |
88 | array $boosts, |
89 | array $decays |
90 | ) { |
91 | $this->fieldQueryBuilder = $fieldQueryBuilder; |
92 | $this->fields = $fields; |
93 | $this->languages = $languages; |
94 | $this->stemmingSettings = $stemmingSettings; |
95 | $this->boosts = $boosts; |
96 | $this->decays = $decays; |
97 | |
98 | parent::__construct( |
99 | array_merge( |
100 | $this->getLanguageAgnosticQueries(), |
101 | $this->getLanguageAwareQueries() |
102 | ) |
103 | ); |
104 | } |
105 | |
106 | private function getLanguageAgnosticQueries(): array { |
107 | $fields = array_intersect( static::LANGUAGE_AGNOSTIC_FIELDS, $this->fields ); |
108 | |
109 | $queries = []; |
110 | foreach ( $fields as $field ) { |
111 | $boost = $this->boosts[$field] ?: 0; |
112 | if ( $boost > 0 ) { |
113 | $queries[] = $this->fieldQueryBuilder->getQuery( $field, $boost ); |
114 | } |
115 | } |
116 | return $queries; |
117 | } |
118 | |
119 | private function getLanguageAwareQueries(): array { |
120 | $queries = []; |
121 | |
122 | $fields = array_intersect( static::LANGUAGE_AWARE_FIELDS, $this->fields ); |
123 | foreach ( $this->languages as $index => $language ) { |
124 | |
125 | $stemmingEnabledForLanguage = $this->stemmingSettings[$language]['query'] ?? false; |
126 | |
127 | foreach ( $fields as $field ) { |
128 | // decay x% for each fallback language |
129 | $boost = ( $this->boosts[$field] ?? 0 ) * ( ( $this->decays[$field] ?? 1 ) ** $index ); |
130 | |
131 | if ( $boost > 0 ) { |
132 | if ( |
133 | // if stemming is turned on for this language |
134 | $stemmingEnabledForLanguage || |
135 | // or if this field is not a stemmed field |
136 | !in_array( $field, static::STEMMED_FIELDS ) |
137 | ) { |
138 | // parse the language into the field name |
139 | $field = str_replace( '$language', $language, $field ); |
140 | $queries[] = $this->fieldQueryBuilder->getQuery( $field, $boost ); |
141 | } else { |
142 | // Otherwise |
143 | // - this field IS a stemmed field |
144 | // - we do NOT have stemming turned on for this language |
145 | // ... and therefore we cannot query the field. |
146 | // Deal with this by checking if there's a plain equivalent of the stemmed |
147 | // field that has no boost of its own, and if there is then query the plain |
148 | // field instead |
149 | if ( isset( static::STEMMED_TO_PLAIN_FIELDS_MAP[$field] ) ) { |
150 | $plainField = static::STEMMED_TO_PLAIN_FIELDS_MAP[$field]; |
151 | $plainBoost = |
152 | ( $this->boosts[$plainField] ?? 0 ) * |
153 | ( ( $this->decays[$plainField] ?? 1 ) ** $index ); |
154 | if ( $plainBoost == 0 ) { |
155 | $plainField = str_replace( '$language', $language, $plainField ); |
156 | $queries[] = $this->fieldQueryBuilder->getQuery( $plainField, $boost ); |
157 | } |
158 | } |
159 | } |
160 | } |
161 | } |
162 | } |
163 | return $queries; |
164 | } |
165 | } |