DidYouMeanSpellCheck.php in Search API Spellcheck 8.3
File
src/Plugin/views/area/DidYouMeanSpellCheck.php
View source
<?php
namespace Drupal\search_api_spellcheck\Plugin\views\area;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Drupal\Core\Url;
use Drupal\search_api\Plugin\views\filter\SearchApiFulltext;
use Drupal\search_api\Plugin\views\query\SearchApiQuery;
use Drupal\search_api\Query\ResultSetInterface;
use Drupal\views\Plugin\views\area\AreaPluginBase;
class DidYouMeanSpellCheck extends AreaPluginBase {
protected $currentQuery;
protected function defineOptions() {
$options = parent::defineOptions();
$options['search_api_spellcheck_count']['default'] = 1;
$options['search_api_spellcheck_hide_on_result']['default'] = TRUE;
$options['search_api_spellcheck_collate']['default'] = TRUE;
return $options;
}
public function buildOptionsForm(&$form, FormStateInterface $form_state) {
parent::buildOptionsForm($form, $form_state);
$form['search_api_spellcheck_hide_on_result'] = [
'#default_value' => $this->options['search_api_spellcheck_hide_on_result'] ?? TRUE,
'#title' => $this
->t('Hide when the view has results.'),
'#type' => 'checkbox',
];
}
public function query() {
if ($this->query instanceof SearchApiQuery && $this->query
->getIndex()
->getServerInstance()
->supportsFeature('search_api_spellcheck')) {
$keys = $this->query
->getKeys();
if ($keys) {
if (!is_array($keys)) {
throw new \InvalidArgumentException('The selected parse mode for fulltext fields is not compatible to Search API Spellcheck.');
}
$this->query
->setOption('search_api_spellcheck', [
'keys' => array_filter($keys, 'is_int', ARRAY_FILTER_USE_KEY),
'count' => $this->options['search_api_spellcheck_count'],
'collate' => $this->options['search_api_spellcheck_collate'],
]);
}
}
parent::query();
}
public function render($empty = FALSE) {
if (!$this->options['search_api_spellcheck_hide_on_result'] || $empty) {
$result = $this->query
->getSearchApiResults();
if ($spellcheck = $result
->getExtraData('search_api_spellcheck')) {
$filter_field_key = $this
->getFilterFieldKey();
$exposed_input = $this->view
->getExposedInput();
$keys = $exposed_input[$filter_field_key] ?? '';
$new_keys = $spellcheck['collation'] ?? $keys;
if (empty($spellcheck['collation']) && !empty($spellcheck['suggestions'])) {
foreach ($spellcheck['suggestions'] as $key => $values) {
$new_keys = str_ireplace($key, $values[0], $new_keys);
}
}
if ($new_keys !== $keys) {
return [
'#theme' => 'search_api_spellcheck_did_you_mean',
'#label' => $this
->getSuggestionLabel(),
'#link' => $this
->getSuggestionLink($new_keys, $filter_field_key),
];
}
}
}
return [];
}
protected function getCurrentQuery() {
if (NULL === $this->currentQuery) {
$this->currentQuery = \Drupal::request()->query
->all();
}
return $this->currentQuery;
}
protected function getFilterFieldKey() {
$field_key = null;
$filters = $this->view->filter;
foreach ($filters as $filter) {
if (!isset($field_key)) {
if ($filter instanceof SearchApiFulltext && $filter
->isExposed()) {
$exposed_info = $filter
->exposedInfo();
$field_key = $exposed_info['value'];
}
}
}
return $field_key;
}
protected function getSuggestionLabel() {
return $this
->t('Did you mean:');
}
protected function getSuggestionLink($new_keys, $filter_name) {
$url = Url::fromRoute('<current>', [
$filter_name => $new_keys,
] + $this
->getCurrentQuery());
return Link::fromTextAndUrl($new_keys, $url);
}
}