You are here

function search_api_autocomplete_form_views_exposed_form_alter in Search API Autocomplete 8

Same name and namespace in other branches
  1. 7 search_api_autocomplete.search_api_views.inc \search_api_autocomplete_form_views_exposed_form_alter()

Implements hook_form_FORM_ID_alter() for "views_exposed_form".

Adds autocompletion to input fields for fulltext keywords on views with exposed filters.

See also

\Drupal\views\Form\ViewsExposedForm

\Drupal\search_api_autocomplete\Plugin\search_api_autocomplete\search\Views

File

./search_api_autocomplete.module, line 81
Adds autocomplete capabilities for Search API searches.

Code

function search_api_autocomplete_form_views_exposed_form_alter(array &$form, FormStateInterface $form_state) {

  /** @var \Drupal\views\ViewExecutable $view */
  $view = $form_state
    ->get('view');
  if (substr($view->storage
    ->get('base_table'), 0, 17) != 'search_api_index_') {
    return;
  }
  $plugin_id = 'views:' . $view
    ->id();
  $cache_tag = "search_api_autocomplete_search_list:{$plugin_id}";
  if (!isset($form['#cache']['tags']) || !in_array($cache_tag, $form['#cache']['tags'])) {
    $form['#cache']['tags'][] = $cache_tag;
  }

  /** @var \Drupal\search_api_autocomplete\Entity\SearchStorage $search_storage */
  $search_storage = \Drupal::entityTypeManager()
    ->getStorage('search_api_autocomplete_search');
  $search = $search_storage
    ->loadBySearchPlugin($plugin_id);
  if (!$search || !$search
    ->status()) {
    return;
  }
  $config = $search
    ->getSearchPlugin()
    ->getConfiguration();
  $selected = in_array($view->current_display, $config['displays']['selected']);

  // @todo Replace with \Drupal\search_api\Utility\Utility::matches() once
  //   we can use it (Search API 1.8 dependency).
  if ($selected == $config['displays']['default']) {
    return;
  }
  $fields = $search
    ->getIndex()
    ->getFulltextFields();
  if (!$fields) {
    return;
  }

  // Add the "Search: Fulltext search" filter as another text field.
  $fields[] = 'search_api_fulltext';
  \Drupal::moduleHandler()
    ->alter('search_api_autocomplete_views_fulltext_fields', $fields, $search, $view);
  $base_data = [
    'display' => $view->current_display,
    'arguments' => $view->args,
  ];
  foreach ($view->filter as $filter_name => $filter) {
    if (!in_array($filter->realField, $fields) || empty($filter->options['expose']['identifier'])) {
      continue;
    }
    $key = $filter->options['expose']['identifier'];
    if (isset($form[$key])) {
      $element =& $form[$key];
    }
    elseif (isset($form[$key . '_wrapper'][$key])) {
      $element =& $form[$key . '_wrapper'][$key];
    }
    else {
      continue;
    }
    $data = $base_data;

    // The Views filter for individual fulltext fields uses a nested "value"
    // field for the real input, due to Views internals.
    if (!empty($element['value'])) {
      $element =& $element['value'];

      // In this case, we also need to manually pass the fulltext fields, so
      // they will be applied properly.
      $data['field'] = $filter->realField;
    }
    if (isset($element['#type']) && $element['#type'] === 'textfield') {
      $data['filter'] = $key;
      \Drupal::getContainer()
        ->get('search_api_autocomplete.helper')
        ->alterElement($element, $search, $data);
    }
    unset($element);
  }
}