This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | |||
3 | /** |
||
4 | * @file |
||
5 | * Provides a Elasticsearch-based service class for the Search API. |
||
6 | */ |
||
7 | |||
8 | /** |
||
9 | * Elasticsearch service abstract class. |
||
10 | */ |
||
11 | abstract class SearchApiElasticsearchAbstractService extends SearchApiAbstractService { |
||
12 | |||
13 | abstract protected function getClusterHealth(); |
||
14 | abstract protected function getClusterState(); |
||
15 | abstract protected function getTransportOptions(); |
||
16 | abstract protected function getSettings(SearchApiIndex $index); |
||
17 | abstract protected function updateSettings(SearchApiIndex $index, $data); |
||
18 | |||
19 | /** |
||
20 | * {@inheritdoc} |
||
21 | */ |
||
22 | public function supportsFeature($feature) { |
||
23 | $this->_supportedFeatures = drupal_map_assoc(array('search_api_service_extra')); |
||
24 | } |
||
25 | |||
26 | /** |
||
27 | * Overrides configurationForm(). |
||
28 | */ |
||
29 | public function configurationForm(array $form, array &$form_state) { |
||
30 | $options = $this->options + array( |
||
31 | 'host' => '127.0.0.1', |
||
32 | 'port' => 9200, |
||
33 | 'path' => '', |
||
34 | 'url' => NULL, |
||
35 | 'transport' => 'Http', |
||
36 | 'persistent' => TRUE, |
||
37 | 'timeout' => 300, |
||
38 | 'log' => FALSE, |
||
39 | 'retryOnConflict' => 0, |
||
40 | ); |
||
41 | |||
42 | // Daemon settings. |
||
43 | $form['daemon_settings'] = array( |
||
44 | '#type' => 'fieldset', |
||
45 | '#title' => t('Elasticsearch client settings'), |
||
46 | '#tree' => TRUE, |
||
47 | '#prefix' => '<div id="elasticsearch-ajax-wrapper">', |
||
48 | '#suffix' => '</div>', |
||
49 | ); |
||
50 | |||
51 | $delta = 1; |
||
52 | $i = 1; |
||
53 | if (isset($form_state['values']['options']['form']) && !empty($form_state['values']['options']['form']) && !isset($form_state['values']['remove_delta'])) { |
||
54 | unset($form_state['values']['options']['form']['add_more']); |
||
55 | View Code Duplication | if (isset($form_state['values']['options']['form']['facet_limit'])) { |
|
0 ignored issues
–
show
|
|||
56 | unset($form_state['values']['options']['form']['facet_settings']); |
||
57 | unset($form_state['values']['options']['form']['facet_limit']); |
||
58 | } |
||
59 | |||
60 | $delta = count($form_state['values']['options']['form']) + 1; |
||
61 | } |
||
62 | elseif (isset($form_state['values']['remove_delta'])) { |
||
63 | unset($form_state['values']['options']['form']['add_more']); |
||
64 | View Code Duplication | if (isset($form_state['values']['options']['form']['facet_limit'])) { |
|
0 ignored issues
–
show
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. ![]() |
|||
65 | unset($form_state['values']['options']['form']['facet_settings']); |
||
66 | unset($form_state['values']['options']['form']['facet_limit']); |
||
67 | } |
||
68 | |||
69 | $delta = count($form_state['values']['options']['form']); |
||
70 | } |
||
71 | elseif (isset($this->options) && !empty($this->options)) { |
||
72 | if (isset($this->options['facet_limit'])) { |
||
73 | unset($this->options['facet_limit']); |
||
74 | } |
||
75 | $delta = count($this->options); |
||
76 | } |
||
77 | |||
78 | for ($c = 0; $c < $delta; $c++) { |
||
79 | if (isset($form_state['values']['remove_delta']) && $c == $form_state['values']['remove_delta']) { |
||
80 | unset($form_state['values']['options']['form'][$form_state['values']['remove_delta']]); |
||
81 | continue; |
||
82 | } |
||
83 | else { |
||
84 | // Daemon settings. |
||
85 | $form['daemon_settings']['fieldset'][$c] = array( |
||
86 | '#type' => 'fieldset', |
||
87 | '#title' => t('Node :id', array(':id' => $i)), |
||
88 | '#tree' => TRUE, |
||
89 | '#collapsible' => TRUE, |
||
90 | '#collapsed' => TRUE, |
||
91 | ); |
||
92 | |||
93 | // Elasticsearch daemon host. |
||
94 | $form['daemon_settings']['fieldset'][$c]['host'] = array( |
||
95 | '#type' => 'textfield', |
||
96 | '#title' => t('Host'), |
||
97 | '#description' => t('Host to which the elasticsearch daemon will listen for this server. Default is %default.', array( |
||
98 | '%default' => $options['host'], |
||
99 | )), |
||
100 | '#required' => TRUE, |
||
101 | '#default_value' => isset($options[$c]['host']) ? $options[$c]['host'] : $options['host'], |
||
102 | '#parents' => array('options', 'form', $c, 'host'), |
||
103 | ); |
||
104 | |||
105 | // Elasticsearch daemon port. |
||
106 | $form['daemon_settings']['fieldset'][$c]['port'] = array( |
||
107 | '#type' => 'textfield', |
||
108 | '#title' => t('Port'), |
||
109 | '#description' => t('Port to which the elasticsearch daemon will listen for this server. Default is %default.', array( |
||
110 | '%default' => $options['port'], |
||
111 | )), |
||
112 | '#required' => TRUE, |
||
113 | '#default_value' => isset($options[$c]['port']) ? $options[$c]['port'] : $options['port'], |
||
114 | '#parents' => array('options', 'form', $c, 'port'), |
||
115 | ); |
||
116 | |||
117 | //Elasticsearch basic authentication. |
||
118 | $form['daemon_settings']['fieldset'][$c]['headers'] = array( |
||
119 | '#type' => 'fieldset', |
||
120 | '#tree' => TRUE, |
||
121 | '#title' => t('HTTP Basic Authentication'), |
||
122 | '#description' => t('If your Elasticsearch server is protected by basic HTTP authentication, enter the login data here.'), |
||
123 | ); |
||
124 | |||
125 | //Elasticsearch basic authentication username. |
||
126 | $form['daemon_settings']['fieldset'][$c]['headers']['http_user'] = array( |
||
127 | '#type' => 'textfield', |
||
128 | '#title' => t('Username'), |
||
129 | '#default_value' => (!empty($options[$c]['headers']) && !empty($options[$c]['headers']['http_user'])) ? $options[$c]['headers']['http_user'] : '', |
||
130 | '#parents' => array('options', 'form', $c, 'headers', 'http_user'), |
||
131 | ); |
||
132 | |||
133 | //Elasticsearch basic password. |
||
134 | $form['daemon_settings']['fieldset'][$c]['headers']['http_pass'] = array( |
||
135 | '#type' => 'password', |
||
136 | '#title' => t('Password'), |
||
137 | '#parents' => array('options', 'form', $c, 'headers', 'http_pass'), |
||
138 | ); |
||
139 | |||
140 | //Elasticsearch basic authentication. |
||
141 | $form['daemon_settings']['fieldset'][$c]['aws'] = array( |
||
142 | '#type' => 'fieldset', |
||
143 | '#tree' => TRUE, |
||
144 | '#title' => t('AWS IAM Authentication'), |
||
145 | '#description' => t('If your Elasticsearch server is protected by basic AWS authentication, enter the IAM credentials here, you shoul use the AwsAuthV4 transporter.'), |
||
146 | ); |
||
147 | |||
148 | //Elasticsearch AWS Access Key. |
||
149 | $form['daemon_settings']['fieldset'][$c]['aws']['aws_access_key_id'] = array( |
||
150 | '#type' => 'textfield', |
||
151 | '#title' => t('Access Key'), |
||
152 | '#default_value' => (!empty($options[$c]['aws']) && !empty($options[$c]['aws']['aws_access_key_id'])) ? $options[$c]['aws']['aws_access_key_id'] : '', |
||
153 | '#description' => t('IAM Access Key ID.'), |
||
154 | '#parents' => array('options', 'form', $c, 'aws', 'aws_access_key_id'), |
||
155 | ); |
||
156 | |||
157 | //Elasticsearch AWS Secret Key. |
||
158 | $form['daemon_settings']['fieldset'][$c]['aws']['aws_secret_access_key'] = array( |
||
159 | '#type' => 'textfield', |
||
160 | '#title' => t('Secret Key'), |
||
161 | '#default_value' => (!empty($options[$c]['aws']) && !empty($options[$c]['aws']['aws_secret_access_key'])) ? $options[$c]['aws']['aws_secret_access_key'] : '', |
||
162 | '#description' => t('IAM Secret Access Key.'), |
||
163 | '#parents' => array('options', 'form', $c, 'aws', 'aws_secret_access_key'), |
||
164 | ); |
||
165 | |||
166 | //Elasticsearch AWS Region. |
||
167 | $form['daemon_settings']['fieldset'][$c]['aws']['aws_region'] = array( |
||
168 | '#type' => 'textfield', |
||
169 | '#title' => t('AWS Region'), |
||
170 | '#default_value' => (!empty($options[$c]['aws']) && !empty($options[$c]['aws']['aws_region'])) ? $options[$c]['aws']['aws_region'] : '', |
||
171 | '#description' => t('Region where is installed your ElasticSearch Service Instance.'), |
||
172 | '#parents' => array('options', 'form', $c, 'aws', 'aws_region'), |
||
173 | ); |
||
174 | |||
175 | // Elasticsearch daemon path. |
||
176 | $form['daemon_settings']['fieldset'][$c]['path'] = array( |
||
177 | '#type' => 'textfield', |
||
178 | '#title' => t('Elasticsearch path prefix'), |
||
179 | '#description' => t('Normally empty. Use when you have remapped the Elasticsearch server API path.'), |
||
180 | '#required' => FALSE, |
||
181 | '#default_value' => isset($options[$c]['path']) ? $options[$c]['path'] : $options['path'], |
||
182 | '#parents' => array('options', 'form', $c, 'path'), |
||
183 | ); |
||
184 | |||
185 | // Elasticsearch daemon URL. |
||
186 | $form['daemon_settings']['fieldset'][$c]['url'] = array( |
||
187 | '#type' => 'textfield', |
||
188 | '#title' => t('Elasticsearch url'), |
||
189 | '#description' => t('Normally empty. Use instead of host/port when you have remapped the Elasticsearch server API url.'), |
||
190 | '#required' => FALSE, |
||
191 | '#default_value' => isset($options[$c]['url']) ? $options[$c]['url'] : $options['url'], |
||
192 | '#parents' => array('options', 'form', $c, 'url'), |
||
193 | ); |
||
194 | |||
195 | // Elasticsearch daemon transport. |
||
196 | $form['daemon_settings']['fieldset'][$c]['transport'] = array( |
||
197 | '#type' => 'select', |
||
198 | '#title' => t('Select transport'), |
||
199 | '#description' => t('Transport to connect to this elasticsearch server.'), |
||
200 | '#options' => $this->getTransportOptions(), |
||
201 | '#default_value' => isset($options[$c]['transport']) ? $options[$c]['transport'] : $options['transport'], |
||
202 | '#parents' => array('options', 'form', $c, 'transport'), |
||
203 | ); |
||
204 | |||
205 | // Elasticsearch daemon persistent. |
||
206 | $form['daemon_settings']['fieldset'][$c]['persistent'] = array( |
||
207 | '#type' => 'checkbox', |
||
208 | '#title' => t('Persistent connection'), |
||
209 | '#description' => t('Use persistent connection when connecting to this node.'), |
||
210 | '#default_value' => isset($options[$c]['persistent']) ? $options[$c]['persistent'] : $options['persistent'], |
||
211 | '#parents' => array('options', 'form', $c, 'persistent'), |
||
212 | ); |
||
213 | |||
214 | // Elasticsearch daemon timeout. |
||
215 | $form['daemon_settings']['fieldset'][$c]['timeout'] = array( |
||
216 | '#type' => 'textfield', |
||
217 | '#title' => t('Timeout in ms'), |
||
218 | '#description' => t('Timeout in ms for waiting this elastic server to respond'), |
||
219 | '#default_value' => isset($options[$c]['timeout']) ? $options[$c]['timeout'] : $options['timeout'], |
||
220 | '#parents' => array('options', 'form', $c, 'timeout'), |
||
221 | ); |
||
222 | |||
223 | // Elasticsearch daemon log. |
||
224 | $form['daemon_settings']['fieldset'][$c]['log'] = array( |
||
225 | '#type' => 'checkbox', |
||
226 | '#title' => t('Log'), |
||
227 | '#description' => t('Log this elasticsearch server queries to the default log.'), |
||
228 | '#default_value' => isset($options[$c]['log']) ? $options[$c]['log'] : $options['log'], |
||
229 | '#parents' => array('options', 'form', $c, 'log'), |
||
230 | ); |
||
231 | |||
232 | if (!class_exists('\Psr\Log\AbstractLogger')) { |
||
233 | $form['daemon_settings']['fieldset'][$c]['log']['#disabled'] = TRUE; |
||
234 | $form['daemon_settings']['fieldset'][$c]['log']['#description'] = t('Logging Elasticsearch queries requires the <a href="@psr3_url">PSR-3 logger</a> to be installed and available. It is recommended to install the <a href="@psr3_watchdog_url">PSR-3 Watchdog module</a> or <a href="@monolog_url">Monolog module</a>.', array('@psr_url' => url('https://packagist.org/packages/psr/log'), '@psr3_watchdog_url' => url('https://drupal.org/project/psr3_watchdog'), '@monolog_url' => url('https://www.drupal.org/project/monolog'))); |
||
235 | } |
||
236 | |||
237 | // Elasticsearch daemon retryOnConflict. |
||
238 | $form['daemon_settings']['fieldset'][$c]['retryOnConflict'] = array( |
||
239 | '#type' => 'textfield', |
||
240 | '#title' => t('retryOnConflict'), |
||
241 | '#description' => t('Sets the number of retries of a version conflict occurs because the document was updated between getting it and updating it.'), |
||
242 | '#default_value' => isset($options[$c]['retryOnConflict']) ? $options[$c]['retryOnConflict'] : $options['retryOnConflict'], |
||
243 | '#parents' => array('options', 'form', $c, 'retryOnConflict'), |
||
244 | ); |
||
245 | |||
246 | if ((!isset($form_state['values']['remove_delta']) && $delta > 1) || (isset($form_state['values']['remove_delta']) && $delta > 2)) { |
||
247 | // Elasticsearch daemon retryOnConflict. |
||
248 | $form['daemon_settings']['fieldset'][$c]['remove_node'] = array( |
||
249 | '#type' => 'submit', |
||
250 | '#value' => t('Remove node') . ' ' . $i, |
||
251 | '#submit' => array('_search_api_elasticsearch_configuration_form_remove_custom'), |
||
252 | '#ajax' => array( |
||
253 | 'callback' => '_search_api_elasticsearch_configuration_form_remove_ajax', |
||
254 | 'wrapper' => 'elasticsearch-ajax-wrapper', |
||
255 | 'method' => 'replace', |
||
256 | 'effect' => 'fade', |
||
257 | ), |
||
258 | '#remove_delta' => $c, |
||
259 | '#parents' => array('options', 'form', $c, 'remove_node'), |
||
260 | ); |
||
261 | } |
||
262 | } |
||
263 | $i++; |
||
264 | } |
||
265 | |||
266 | // Elasticsearch daemon retryOnConflict. |
||
267 | $form['add_more'] = array( |
||
268 | '#type' => 'submit', |
||
269 | '#value' => t('+'), |
||
270 | '#submit' => array('_search_api_elasticsearch_configuration_form_submit_custom'), |
||
271 | '#ajax' => array( |
||
272 | 'callback' => '_search_api_elasticsearch_configuration_form_ajax', |
||
273 | 'wrapper' => 'elasticsearch-ajax-wrapper', |
||
274 | 'method' => 'replace', |
||
275 | 'effect' => 'fade', |
||
276 | ), |
||
277 | ); |
||
278 | |||
279 | if (module_exists('search_api_facetapi')) { |
||
280 | // Facet settings. |
||
281 | $form['facet_settings'] = array( |
||
282 | '#type' => 'fieldset', |
||
283 | '#title' => t('Elasticsearch facet settings'), |
||
284 | '#tree' => FALSE, |
||
285 | ); |
||
286 | |||
287 | // Elasticsearch facet limit. |
||
288 | $default = 10; |
||
289 | $form['facet_settings']['facet_limit'] = array( |
||
290 | '#type' => 'textfield', |
||
291 | '#title' => t('Facet limit'), |
||
292 | '#description' => t("Maximum number of facet elements to be returned by the server if 'no limit' is selected as hard limit is the facet option. Default is %default.", array( |
||
293 | '%default' => $default, |
||
294 | )), |
||
295 | '#required' => TRUE, |
||
296 | '#default_value' => (isset($options['facet_limit'])) ? $options['facet_limit'] : $default, |
||
297 | '#parents' => array('options', 'form', 'facet_limit'), |
||
298 | ); |
||
299 | } |
||
300 | |||
301 | return $form; |
||
302 | } |
||
303 | |||
304 | /** |
||
305 | * Overrides configurationFormValidate(). |
||
306 | */ |
||
307 | public function configurationFormValidate(array $form, array &$values, array &$form_state) { |
||
308 | unset($values['add_more']); |
||
309 | $count_nodes = count($values); |
||
0 ignored issues
–
show
$count_nodes is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
310 | |||
311 | if (module_exists('search_api_facetapi')) { |
||
312 | // Facet limit. |
||
313 | if (filter_var($values['facet_limit'], FILTER_VALIDATE_INT, array('options' => array('min_range' => 0))) === FALSE) { |
||
314 | form_set_error('options][form][facet_limit', t('You must enter a positive integer for the elasticsearch facet limit.')); |
||
315 | } |
||
316 | } |
||
317 | |||
318 | $options = $this->getOptions(); |
||
319 | foreach ($values as $i => $setting) { |
||
320 | if ($i != 'facet_limit') { |
||
321 | // Daemon IP address. |
||
322 | if (filter_var($values[$i]['host'], FILTER_VALIDATE_IP) === FALSE) { |
||
323 | form_set_error('options][form]' . $i . '[host', t('You must enter a valid IP address for the elasticsearch daemon.')); |
||
324 | } |
||
325 | |||
326 | // Daemon Port. |
||
327 | if (filter_var($values[$i]['port'], FILTER_VALIDATE_INT, array('options' => array('min_range' => 0, 'max_range' => 65535))) === FALSE) { |
||
328 | form_set_error('options][form]' . $i . '[port', t('You must enter a valid Port (between 0 and 65535) for the elasticsearch daemon.')); |
||
329 | } |
||
330 | |||
331 | $values[$i]['path'] = $this->setPath($values[$i]['path']); |
||
332 | } |
||
333 | |||
334 | // Put http_user and http_password in correct form. |
||
335 | if (!empty($setting['headers']['http_user'])) { |
||
336 | // If username matches the old value and password is empty, then use the old Authentication. |
||
337 | if (empty($setting['headers']['http_pass'])) { |
||
338 | if ($setting['headers']['http_user'] == $options[$i]['headers']['http_user']) { |
||
339 | $values[$i]['headers']['Authorization'] = $options[$i]['headers']['Authorization']; |
||
340 | } |
||
341 | // If username does not match and password is empty, then give a validation error. |
||
342 | else { |
||
343 | form_set_error('http_pass', t('If you are changing the username, you need to supply the password.')); |
||
344 | return; |
||
345 | } |
||
346 | } |
||
347 | else { |
||
348 | $values[$i]['headers']['Authorization'] = 'Basic ' . base64_encode($setting['headers']['http_user'] . ':' . $setting['headers']['http_pass']); |
||
349 | } |
||
350 | } |
||
351 | if (isset($values[$i]['headers']['http_pass'])) { |
||
352 | unset($values[$i]['headers']['http_pass']); |
||
353 | } |
||
354 | |||
355 | // Put aws_access_key_id and aws_secret_access_keyword in correct form. |
||
356 | if (!empty($setting['aws']['aws_access_key_id'])) { |
||
357 | if (empty($setting['aws']['aws_secret_access_key'])) { |
||
358 | form_set_error('aws_secret_access_key', t('Access Secret Key is required to generate the Access token.')); |
||
359 | return; |
||
360 | } |
||
361 | if (empty($setting['aws']['aws_region'])) { |
||
362 | form_set_error('aws_region', t('Region of the Elasticsearch Service must be specified.')); |
||
363 | return; |
||
364 | } |
||
365 | } |
||
366 | View Code Duplication | if (isset($values[$i]['aws']['aws_access_key_id'])) { |
|
0 ignored issues
–
show
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. ![]() |
|||
367 | $values[$i]['aws_access_key_id'] = $values[$i]['aws']['aws_access_key_id']; |
||
368 | } |
||
369 | View Code Duplication | if (isset($values[$i]['aws']['aws_secret_access_key'])) { |
|
0 ignored issues
–
show
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. ![]() |
|||
370 | $values[$i]['aws_secret_access_key'] = $values[$i]['aws']['aws_secret_access_key']; |
||
371 | } |
||
372 | View Code Duplication | if (isset($values[$i]['aws']['aws_region'])) { |
|
0 ignored issues
–
show
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. ![]() |
|||
373 | $values[$i]['aws_region'] = $values[$i]['aws']['aws_region']; |
||
374 | } |
||
375 | } |
||
376 | } |
||
377 | |||
378 | /** |
||
379 | * Overrides configurationFormSubmit(). |
||
380 | */ |
||
381 | public function configurationFormSubmit(array $form, array &$values, array &$form_state) { |
||
382 | $aggregation_limit = ''; |
||
383 | |||
384 | if (isset($values['facet_limit'])) { |
||
385 | $aggregation_limit = $values['facet_limit']; |
||
386 | unset($values['facet_limit']); |
||
387 | } |
||
388 | |||
389 | $values = array_values($values); |
||
390 | $values['facet_limit'] = $aggregation_limit; |
||
391 | $this->options = $values; |
||
392 | } |
||
393 | |||
394 | /** |
||
395 | * Helper function. Parse an option form element. |
||
396 | */ |
||
397 | protected function parseOptionFormElement($element, $key) { |
||
398 | $children_keys = element_children($element); |
||
399 | |||
400 | if (!empty($children_keys)) { |
||
401 | $children = array(); |
||
402 | foreach ($children_keys as $child_key) { |
||
403 | $child = $this->parseOptionFormElement($element[$child_key], $child_key); |
||
404 | if (!empty($child)) { |
||
405 | $children[] = $child; |
||
406 | } |
||
407 | } |
||
408 | if (!empty($children)) { |
||
409 | return array( |
||
410 | 'label' => isset($element['#title']) ? $element['#title'] : $key, |
||
411 | 'option' => $children, |
||
412 | ); |
||
413 | } |
||
414 | } |
||
415 | elseif (isset($this->options[$key])) { |
||
416 | return array( |
||
417 | 'label' => isset($element['#title']) ? $element['#title'] : $key, |
||
418 | 'option' => $key, |
||
419 | ); |
||
420 | } |
||
421 | |||
422 | return array(); |
||
423 | } |
||
424 | |||
425 | /** |
||
426 | * Helper function. Display a setting element. |
||
427 | */ |
||
428 | protected function viewSettingElement($element) { |
||
429 | $output = ''; |
||
430 | |||
431 | if (is_array($element['option'])) { |
||
432 | $value = ''; |
||
433 | foreach ($element['option'] as $sub_element) { |
||
434 | $value .= $this->viewSettingElement($sub_element); |
||
435 | } |
||
436 | } |
||
437 | else { |
||
438 | $value = $this->getOption($element['option']); |
||
439 | $value = nl2br(check_plain(print_r($value, TRUE))); |
||
440 | } |
||
441 | $output .= '<dt><em>' . check_plain($element['label']) . '</em></dt>' . "\n"; |
||
442 | $output .= '<dd>' . $value . '</dd>' . "\n"; |
||
443 | |||
444 | return "<dl>\n{$output}</dl>"; |
||
445 | } |
||
446 | |||
447 | /** |
||
448 | * Helper function. Get the Elasticsearch mapping for a field. |
||
449 | */ |
||
450 | protected function getFieldMapping($field) { |
||
451 | $field_type = (isset($field['real_type'])) ? $field['real_type'] : $field['type']; |
||
452 | $type = search_api_extract_inner_type($field_type); |
||
453 | |||
454 | switch ($type) { |
||
455 | case 'text': |
||
456 | return array( |
||
457 | 'type' => 'string', |
||
458 | 'boost' => $field['boost'], |
||
459 | ); |
||
460 | |||
461 | case 'uri': |
||
462 | case 'string': |
||
463 | case 'token': |
||
464 | return array( |
||
465 | 'type' => 'string', |
||
466 | 'index' => 'not_analyzed', |
||
467 | ); |
||
468 | |||
469 | case 'integer': |
||
470 | case 'duration': |
||
471 | return array( |
||
472 | 'type' => 'integer', |
||
473 | ); |
||
474 | |||
475 | case 'boolean': |
||
476 | return array( |
||
477 | 'type' => 'boolean', |
||
478 | ); |
||
479 | |||
480 | case 'decimal': |
||
481 | return array( |
||
482 | 'type' => 'float', |
||
483 | ); |
||
484 | |||
485 | case 'date': |
||
486 | return array( |
||
487 | 'type' => 'date', |
||
488 | 'format' => 'date_time', |
||
489 | ); |
||
490 | |||
491 | case 'location': |
||
492 | return array( |
||
493 | 'type' => 'geo_point', |
||
494 | 'lat_lon' => TRUE, |
||
495 | ); |
||
496 | |||
497 | default: |
||
498 | return NULL; |
||
499 | } |
||
500 | } |
||
501 | /** |
||
502 | * Helper function. Return date gap from two dates or timestamps. |
||
503 | * |
||
504 | * @see facetapi_get_timestamp_gap() |
||
505 | */ |
||
506 | protected static function getDateGap($min, $max, $timestamp = TRUE) { |
||
507 | if ($timestamp !== TRUE) { |
||
508 | $min = strtotime($min); |
||
509 | $max = strtotime($max); |
||
510 | } |
||
511 | |||
512 | if (empty($min) || empty($max)) { |
||
513 | return 'DAY'; |
||
514 | } |
||
515 | |||
516 | $diff = $max - $min; |
||
517 | |||
518 | switch (TRUE) { |
||
519 | case ($diff > 86400 * 365): |
||
520 | return 'NONE'; |
||
521 | |||
522 | case ($diff > 86400 * gmdate('t', $min)): |
||
523 | return 'YEAR'; |
||
524 | |||
525 | case ($diff > 86400): |
||
526 | return 'MONTH'; |
||
527 | |||
528 | default: |
||
529 | return 'DAY'; |
||
530 | } |
||
531 | } |
||
532 | |||
533 | /** |
||
534 | * Helper function. Return server options. |
||
535 | */ |
||
536 | protected function getOptions() { |
||
537 | return $this->options; |
||
538 | } |
||
539 | |||
540 | /** |
||
541 | * Helper function. Return a server option. |
||
542 | */ |
||
543 | protected function getOption($option, $default = NULL) { |
||
544 | $options = $this->getOptions(); |
||
545 | return isset($options[$option]) ? $options[$option] : $default; |
||
546 | } |
||
547 | |||
548 | /** |
||
549 | * Helper function. Return index fields. |
||
550 | */ |
||
551 | protected function getIndexFields(SearchApiQueryInterface $query) { |
||
552 | $index = $query->getIndex(); |
||
553 | $index_fields = $index->getFields(); |
||
554 | return $index_fields; |
||
555 | } |
||
556 | |||
557 | /** |
||
558 | * Helper function that return Sort for query in search. |
||
559 | */ |
||
560 | protected function getSortSearchQuery(SearchApiQueryInterface $query) { |
||
561 | |||
562 | $index_fields = $this->getIndexFields($query); |
||
563 | $sort = array(); |
||
564 | foreach ($query->getSort() as $field_id => $direction) { |
||
565 | $direction = drupal_strtolower($direction); |
||
566 | |||
567 | if ($field_id === 'search_api_relevance') { |
||
568 | $sort['_score'] = $direction; |
||
569 | } |
||
570 | elseif (isset($index_fields[$field_id])) { |
||
571 | $sort[$field_id] = $direction; |
||
572 | } |
||
573 | else { |
||
574 | throw new Exception(t('Incorrect sorting!.')); |
||
575 | } |
||
576 | } |
||
577 | return $sort; |
||
578 | } |
||
579 | |||
580 | /** |
||
581 | * Helper function return Facet filter. |
||
582 | */ |
||
583 | protected function getAggregationSearchFilter(SearchApiQueryInterface $query, $aggregation_info) { |
||
584 | $index_fields = $this->getIndexFields($query); |
||
585 | $aggregation_search_filter = ''; |
||
0 ignored issues
–
show
$aggregation_search_filter is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
586 | |||
587 | if (isset($aggregation_info['operator']) && drupal_strtolower($aggregation_info['operator']) == 'or') { |
||
588 | $aggregation_search_filter = $this->parseFilter($query->getFilter(), $index_fields, $aggregation_info['field']); |
||
589 | if (!empty($aggregation_search_filter)) { |
||
590 | $aggregation_search_filter = $aggregation_search_filter[0]; |
||
591 | } |
||
592 | } |
||
593 | // Normal facet, we just use the main query filters. |
||
594 | else { |
||
595 | $aggregation_search_filter = $this->parseFilter($query->getFilter(), $index_fields); |
||
596 | if (!empty($aggregation_search_filter)) { |
||
597 | $aggregation_search_filter = $aggregation_search_filter[0]; |
||
598 | } |
||
599 | } |
||
600 | |||
601 | return $aggregation_search_filter; |
||
602 | } |
||
603 | |||
604 | /** |
||
605 | * Helper function that return facet limits. |
||
606 | */ |
||
607 | protected function getAggregationLimit(array $aggregation_info) { |
||
608 | // If no limit (-1) is selected, use the server facet limit option. |
||
609 | $aggregation_limit = !empty($aggregation_info['limit']) ? $aggregation_info['limit'] : -1; |
||
610 | if ($aggregation_limit < 0) { |
||
611 | $aggregation_limit = $this->getOption('facet_limit', 10); |
||
612 | } |
||
613 | return $aggregation_limit; |
||
614 | } |
||
615 | |||
616 | /** |
||
617 | * Helper function which add params to date facets. |
||
618 | */ |
||
619 | protected function getDateAggregationInterval($aggregation_id) { |
||
620 | // Active search corresponding to this index. |
||
621 | $searcher = key(facetapi_get_active_searchers()); |
||
622 | |||
623 | // Get the FacetApiAdpater for this searcher. |
||
624 | $adapter = isset($searcher) ? facetapi_adapter_load($searcher) : NULL; |
||
625 | |||
626 | // Get the date granularity. |
||
627 | $date_gap = $this->getDateGranularity($adapter, $aggregation_id); |
||
628 | |||
629 | switch ($date_gap) { |
||
630 | // Already a selected YEAR, we want the months. |
||
631 | case 'YEAR': |
||
632 | $date_interval = 'month'; |
||
633 | break; |
||
634 | |||
635 | // Already a selected MONTH, we want the days. |
||
636 | case 'MONTH': |
||
637 | $date_interval = 'day'; |
||
638 | break; |
||
639 | |||
640 | // Already a selected DAY, we want the hours and so on. |
||
641 | case 'DAY': |
||
642 | $date_interval = 'hour'; |
||
643 | break; |
||
644 | |||
645 | // By default we return result counts by year. |
||
646 | default: |
||
647 | $date_interval = 'year'; |
||
648 | } |
||
649 | |||
650 | return $date_interval; |
||
651 | } |
||
652 | |||
653 | /** |
||
654 | * Helper function to return date gap. |
||
655 | */ |
||
656 | protected function getDateGranularity($adapter, $aggregation_id) { |
||
657 | // Date gaps. |
||
658 | $gap_weight = array('YEAR' => 2, 'MONTH' => 1, 'DAY' => 0); |
||
659 | $gaps = array(); |
||
660 | $date_gap = 'YEAR'; |
||
661 | |||
662 | // Get the date granularity. |
||
663 | if (isset($adapter)) { |
||
664 | // Get the current date gap from the active date filters. |
||
665 | $active_items = $adapter->getActiveItems(array('name' => $aggregation_id)); |
||
666 | if (!empty($active_items)) { |
||
667 | foreach ($active_items as $active_item) { |
||
668 | $value = $active_item['value']; |
||
669 | if (strpos($value, ' TO ') > 0) { |
||
670 | list($date_min, $date_max) = explode(' TO ', str_replace(array('[', ']'), '', $value), 2); |
||
671 | $gap = self::getDateGap($date_min, $date_max, FALSE); |
||
672 | if (isset($gap_weight[$gap])) { |
||
673 | $gaps[] = $gap_weight[$gap]; |
||
674 | } |
||
675 | } |
||
676 | } |
||
677 | if (!empty($gaps)) { |
||
678 | // Minimum gap. |
||
679 | $date_gap = array_search(min($gaps), $gap_weight); |
||
680 | } |
||
681 | } |
||
682 | } |
||
683 | |||
684 | return $date_gap; |
||
685 | } |
||
686 | |||
687 | /** |
||
688 | * Helper function that parse facets. |
||
689 | */ |
||
690 | protected function parseSearchAggregation($response, SearchApiQueryInterface $query) { |
||
691 | |||
692 | $result = array(); |
||
693 | $index_fields = $this->getIndexFields($query); |
||
694 | $aggregations = $query->getOption('search_api_facets'); |
||
695 | |||
696 | if (!empty($aggregations) && $response->hasAggregations()) { |
||
697 | foreach ($response->getAggregations() as $aggregation_id => $aggregation_data) { |
||
698 | if (isset($aggregations[$aggregation_id])) { |
||
699 | $aggregation_info = $aggregations[$aggregation_id]; |
||
700 | $aggregation_min_count = $aggregation_info['min_count']; |
||
701 | |||
702 | $field_id = $aggregation_info['field']; |
||
703 | $field_type = search_api_extract_inner_type($index_fields[$field_id]['type']); |
||
704 | |||
705 | // TODO: handle different types (GeoDistance and so on). |
||
706 | if ($field_type === 'date') { |
||
707 | foreach ($aggregation_data['buckets'] as $entry) { |
||
708 | if ($entry['count'] >= $aggregation_min_count) { |
||
709 | // Divide time by 1000 as we want seconds from epoch |
||
710 | // not milliseconds. |
||
711 | $result[$aggregation_id][] = array( |
||
712 | 'count' => $entry['count'], |
||
713 | 'filter' => '"' . ($entry['time'] / 1000) . '"', |
||
714 | ); |
||
715 | } |
||
716 | } |
||
717 | } |
||
718 | else { |
||
719 | foreach ($aggregation_data['buckets'] as $term) { |
||
720 | if ($term['doc_count'] >= $aggregation_min_count) { |
||
721 | $result[$aggregation_id][] = array( |
||
722 | 'count' => $term['doc_count'], |
||
723 | 'filter' => '"' . $term['key'] . '"', |
||
724 | ); |
||
725 | } |
||
726 | } |
||
727 | } |
||
728 | } |
||
729 | } |
||
730 | } |
||
731 | |||
732 | return $result; |
||
733 | } |
||
734 | |||
735 | /** |
||
736 | * Helper function. Return the path in the correct format. |
||
737 | */ |
||
738 | protected function setPath($path) { |
||
739 | if (isset($path) && !empty($path)) { |
||
740 | $trimmed_path = trim($path, '/'); |
||
741 | $path = $trimmed_path . '/'; |
||
742 | } |
||
743 | |||
744 | return $path; |
||
745 | } |
||
746 | |||
747 | /** |
||
748 | * Helper function. Escape a field or index name. |
||
749 | * |
||
750 | * Force names to be strictly alphanumeric-plus-underscore. |
||
751 | */ |
||
752 | protected static function escapeName($name) { |
||
753 | return preg_replace('/[^A-Za-z0-9_]+/', '', $name); |
||
754 | } |
||
755 | |||
756 | /** |
||
757 | * Helper function. Get Autocomplete suggestions. |
||
758 | * |
||
759 | * @param SearchApiQueryInterface $query |
||
760 | * @param SearchApiAutocompleteSearch $search |
||
761 | * @param string $incomplete_key |
||
762 | * @param string $user_input |
||
763 | */ |
||
764 | public function getAutocompleteSuggestions(SearchApiQueryInterface $query, SearchApiAutocompleteSearch $search, $incomplete_key, $user_input) { |
||
765 | $suggestions = array(); |
||
766 | // Turn inputs to lower case, otherwise we get case sensivity problems. |
||
767 | $incomp = drupal_strtolower($incomplete_key); |
||
0 ignored issues
–
show
$incomp is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
768 | |||
769 | $index = $query->getIndex(); |
||
770 | $index_fields = $this->getIndexFields($query); |
||
0 ignored issues
–
show
$index_fields is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
771 | |||
772 | $complete = $query->getOriginalKeys(); |
||
0 ignored issues
–
show
$complete is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
773 | $query->keys($user_input); |
||
774 | |||
775 | try { |
||
776 | $response = $this->search($query); |
||
777 | } |
||
778 | catch (Exception $e) { |
||
779 | watchdog('Elasticsearch', check_plain($e->getMessage()), array(), WATCHDOG_ERROR); |
||
780 | return array(); |
||
781 | } |
||
782 | |||
783 | $matches = array(); |
||
784 | if (isset($response['results'])) { |
||
785 | $items = $index->loadItems(array_keys($response['results'])); |
||
786 | foreach ($items as $id => $item) { |
||
787 | $node_title = $index->datasource()->getItemLabel($item); |
||
788 | $matches[$node_title] = $node_title; |
||
789 | } |
||
790 | |||
791 | if ($matches) { |
||
0 ignored issues
–
show
The expression
$matches of type array 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 ![]() |
|||
792 | // Eliminate suggestions that are too short or already in the query. |
||
793 | foreach ($matches as $name => $node_title) { |
||
794 | if (drupal_strlen($name) < 3 || isset($keys_array[$name])) { |
||
795 | unset($matches[$name]); |
||
796 | } |
||
797 | } |
||
798 | |||
799 | // The $count in this array is actually a score. We want the |
||
800 | // highest ones first. |
||
801 | arsort($matches); |
||
802 | |||
803 | // Shorten the array to the right ones. |
||
804 | $additional_matches = array_slice($matches, $limit - count($suggestions), NULL, TRUE); |
||
0 ignored issues
–
show
$additional_matches is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
805 | $matches = array_slice($matches, 0, $limit, TRUE); |
||
806 | |||
807 | foreach ($matches as $node => $name) { |
||
808 | $suggestions[] = $name; |
||
809 | } |
||
810 | } |
||
811 | $keys = trim($keys . ' ' . $incomplete_key); |
||
0 ignored issues
–
show
The variable
$keys seems only to be defined at a later point. Did you maybe move this code here without moving the variable definition?
This error can happen if you refactor code and forget to move the variable initialization. Let’s take a look at a simple example: function someFunction() {
$x = 5;
echo $x;
}
The above code is perfectly fine. Now imagine that we re-order the statements: function someFunction() {
echo $x;
$x = 5;
}
In that case, ![]() $keys is not used, you could remove the assignment.
This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently. $myVar = 'Value';
$higher = false;
if (rand(1, 6) > 3) {
$higher = true;
} else {
$higher = false;
}
Both the ![]() |
|||
812 | return $suggestions; |
||
813 | } |
||
814 | } |
||
815 | |||
816 | /** |
||
817 | * Helper function: Recursively parse Search API filters. |
||
818 | */ |
||
819 | View Code Duplication | protected function parseFilter(SearchApiQueryFilter $query_filter, $index_fields, $ignored_field_id = '') { |
|
0 ignored issues
–
show
This method seems to be duplicated in 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. ![]() |
|||
820 | |||
821 | if (empty($query_filter)) { |
||
822 | return NULL; |
||
823 | } |
||
824 | else { |
||
825 | $conjunction = $query_filter->getConjunction(); |
||
826 | |||
827 | $filters = array(); |
||
828 | |||
829 | try { |
||
830 | foreach ($query_filter->getFilters() as $filter_info) { |
||
831 | $filter = NULL; |
||
832 | |||
833 | // Simple filter [field_id, value, operator]. |
||
834 | if (is_array($filter_info)) { |
||
835 | $filter_assoc = $this->getAssociativeFilter($filter_info); |
||
836 | $this->correctFilter($filter_assoc, $index_fields, $ignored_field_id); |
||
837 | // Check field. |
||
838 | $filter = $this->getFilter($filter_assoc); |
||
839 | |||
840 | if (!empty($filter)) { |
||
841 | $filters[] = $filter; |
||
842 | } |
||
843 | } |
||
844 | // Nested filters. |
||
845 | elseif ($filter_info instanceof SearchApiQueryFilter) { |
||
0 ignored issues
–
show
The class
SearchApiQueryFilter does not exist. Did you forget a USE statement, or did you not list all dependencies?
This error could be the result of: 1. Missing dependenciesPHP Analyzer uses your Are you sure this class is defined by one of your dependencies, or did you maybe
not list a dependency in either the 2. Missing use statementPHP does not complain about undefined classes in if ($x instanceof DoesNotExist) {
// Do something.
}
If you have not tested against this specific condition, such errors might go unnoticed. ![]() |
|||
846 | $nested_filters = $this->parseFilter($filter_info, $index_fields, $ignored_field_id); |
||
847 | // TODO: handle error. - here is unnecessary cause in if we thow exceptions and this is still in try{} . |
||
848 | if (!empty($nested_filters)) { |
||
849 | $filters = array_merge($filters, $nested_filters); |
||
850 | } |
||
851 | } |
||
852 | } |
||
853 | $filters = $this->setFiltersConjunction($filters, $conjunction); |
||
854 | } |
||
855 | catch (Exception $e) { |
||
856 | watchdog('Elasticsearch', check_plain($e->getMessage()), array(), WATCHDOG_ERROR); |
||
857 | drupal_set_message(check_plain($e->getMessage()), 'error'); |
||
858 | } |
||
859 | |||
860 | return $filters; |
||
861 | } |
||
862 | } |
||
863 | |||
864 | /** |
||
865 | * Helper function that return associative array of filters info. |
||
866 | */ |
||
867 | View Code Duplication | protected function getAssociativeFilter(array $filter_info) { |
|
0 ignored issues
–
show
This method seems to be duplicated in 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. ![]() |
|||
868 | |||
869 | $filter_operator = str_replace('!=', '<>', $filter_info[2]); |
||
870 | return array( |
||
871 | 'field_id' => $filter_info[0], |
||
872 | 'filter_value' => $filter_info[1], |
||
873 | 'filter_operator' => $filter_operator, |
||
874 | ); |
||
875 | } |
||
876 | |||
877 | /** |
||
878 | * Helper function that check if filter is set correct. |
||
879 | */ |
||
880 | protected function correctFilter($filter_assoc, $index_fields, $ignored_field_id = '') { |
||
881 | if (!isset($filter_assoc['field_id']) || !isset($filter_assoc['filter_value']) |
||
882 | || !isset($filter_assoc['filter_operator'])) { |
||
883 | throw new Exception(t('Incorrect filter criteria is using for searching!')); |
||
884 | } |
||
885 | |||
886 | $field_id = $filter_assoc['field_id']; |
||
887 | View Code Duplication | if (!isset($index_fields[$field_id])) { |
|
0 ignored issues
–
show
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. ![]() |
|||
888 | throw new Exception(t(':field_id Undefined field ! Incorrect filter criteria is using for searching!', array(':field_id' => $field_id))); |
||
889 | } |
||
890 | |||
891 | // Check operator. |
||
892 | if (empty($filter_assoc['filter_operator'])) { |
||
893 | throw new Exception(t('Empty filter operator for :field_id field! Incorrect filter criteria is using for searching!', array(':field_id' => $field_id))); |
||
894 | } |
||
895 | |||
896 | // If field should be ignored, we skip. |
||
897 | if ($field_id === $ignored_field_id) { |
||
898 | return TRUE; |
||
899 | } |
||
900 | |||
901 | return TRUE; |
||
902 | } |
||
903 | |||
904 | /** |
||
905 | * Return a full text search query. |
||
906 | * |
||
907 | * TODO: better handling of parse modes. |
||
908 | */ |
||
909 | protected function flattenKeys($keys, $parse_mode = '', $full_text_fields = array()) { |
||
910 | $conjunction = isset($keys['#conjunction']) ? $keys['#conjunction'] : 'AND'; |
||
911 | $negation = !empty($keys['#negation']); |
||
912 | $values = array(); |
||
913 | |||
914 | foreach (element_children($keys) as $key) { |
||
915 | $value = $keys[$key]; |
||
916 | |||
917 | if (empty($value)) { |
||
918 | continue; |
||
919 | } |
||
920 | |||
921 | if (is_array($value)) { |
||
922 | $values[] = $this->flattenKeys($value); |
||
923 | } |
||
924 | elseif (is_string($value)) { |
||
925 | // If parse mode is not "direct": quote the keyword. |
||
926 | if ($parse_mode !== 'direct') { |
||
927 | $value = '"' . $value . '"'; |
||
928 | } |
||
929 | |||
930 | $values[] = $value; |
||
931 | } |
||
932 | } |
||
933 | if (!empty($values)) { |
||
934 | return ($negation === TRUE ? 'NOT ' : '') . '(' . implode(" {$conjunction} ", $values) . ')'; |
||
935 | } |
||
936 | else { |
||
937 | return ''; |
||
938 | } |
||
939 | } |
||
940 | |||
941 | /** |
||
942 | * Helper function. Returns the elasticsearch name of an index. |
||
943 | */ |
||
944 | protected function getIndexName(SearchApiIndex $index) { |
||
945 | global $databases; |
||
946 | |||
947 | $site_database = $databases['default']['default']['database']; |
||
948 | |||
949 | $index_machine_name = is_string($index) ? $index : $index->machine_name; |
||
950 | |||
951 | return self::escapeName('elasticsearch_index_' . $site_database . '_' . $index_machine_name); |
||
952 | } |
||
953 | |||
954 | /** |
||
955 | * Overrides fieldsUpdated(). |
||
956 | * |
||
957 | * We only do the grunt work of building the array of properties. This allows |
||
958 | * submodules who just need an array of properties to simply call this as a |
||
959 | * parent method to have the array built for them, thus implementing the DRY |
||
960 | * principle. The submodule is responsible for the return value. |
||
961 | * |
||
962 | * @param SearchApiIndex $index |
||
963 | * The Search API index. |
||
964 | */ |
||
965 | public function fieldsUpdated(SearchApiIndex $index) { |
||
966 | $this->fieldsUpdatedProperties = array( |
||
967 | 'id' => array('type' => 'string', 'include_in_all' => FALSE), |
||
968 | ); |
||
969 | foreach ($index->getFields() as $field_id => $field_data) { |
||
970 | $this->fieldsUpdatedProperties[$field_id] = $this->getFieldMapping($field_data); |
||
971 | } |
||
972 | |||
973 | // Allow other modules to alter properties. |
||
974 | drupal_alter('search_api_elasticsearch_fields_updated', $index, $this->fieldsUpdatedProperties); |
||
975 | } |
||
976 | |||
977 | /** |
||
978 | * Get analyzers for an Elasticsearch index. |
||
979 | * |
||
980 | * @param SearchApiIndex $index |
||
981 | * A Search API index object. |
||
982 | * |
||
983 | * @return array | bool |
||
984 | * An array of available analyzers. FALSE if none. |
||
985 | */ |
||
986 | public function getAnalysisSettings(SearchApiIndex $index) { |
||
987 | $settings = $this->getSettings($index); |
||
988 | return isset($settings['analysis']) ? $settings['analysis'] : FALSE; |
||
989 | } |
||
990 | |||
991 | /** |
||
992 | * {@inheritdoc} |
||
993 | */ |
||
994 | public function getExtraInformation() { |
||
995 | $info = array(); |
||
996 | |||
997 | $cluster_health = $this->getClusterHealth(); |
||
998 | if (!empty($cluster_health)) { |
||
999 | $info[] = array( |
||
1000 | 'label' => t('Cluster Name'), |
||
1001 | 'info' => $cluster_health['cluster_name'], |
||
1002 | ); |
||
1003 | $info[] = array( |
||
1004 | 'label' => t('Cluster Status'), |
||
1005 | 'info' => $cluster_health['status'], |
||
1006 | ); |
||
1007 | $info[] = array( |
||
1008 | 'label' => t('Number of Nodes'), |
||
1009 | 'info' => $cluster_health['number_of_nodes'], |
||
1010 | ); |
||
1011 | $info[] = array( |
||
1012 | 'label' => t('Number of Data Nodes'), |
||
1013 | 'info' => $cluster_health['number_of_data_nodes'], |
||
1014 | ); |
||
1015 | $info[] = array( |
||
1016 | 'label' => t('Active Primary Shards'), |
||
1017 | 'info' => $cluster_health['active_primary_shards'], |
||
1018 | ); |
||
1019 | $info[] = array( |
||
1020 | 'label' => t('Active Shards'), |
||
1021 | 'info' => $cluster_health['active_shards'], |
||
1022 | ); |
||
1023 | $info[] = array( |
||
1024 | 'label' => t('Relocating Shards'), |
||
1025 | 'info' => $cluster_health['relocating_shards'], |
||
1026 | ); |
||
1027 | $info[] = array( |
||
1028 | 'label' => t('Initializing Shards'), |
||
1029 | 'info' => $cluster_health['initializing_shards'], |
||
1030 | ); |
||
1031 | $info[] = array( |
||
1032 | 'label' => t('Unassigned Shards'), |
||
1033 | 'info' => $cluster_health['unassigned_shards'], |
||
1034 | ); |
||
1035 | } |
||
1036 | |||
1037 | return $info; |
||
1038 | } |
||
1039 | } |
||
1040 |
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.