You are here

function search_api_form_views_exposed_form_alter in Search API 8

Implements hook_form_FORM_ID_alter() for views_exposed_form().

Custom integration for facets. When a Views exposed filter is modified on a search results page it will lose any facets which have been already selected. This adds hidden fields for each facet so their values are retained.

File

./search_api.module, line 562
Provides a rich framework for creating searches.

Code

function search_api_form_views_exposed_form_alter(&$form, FormStateInterface $form_state) {

  // Retrieve the view object and the query plugin.
  $storage = $form_state
    ->getStorage();
  if (!isset($storage['view'])) {
    return;
  }
  $view = $storage['view'];
  if (!$view instanceof ViewExecutable) {
    return;
  }
  $query_plugin = $view
    ->getQuery();

  // Make sure the view is based on Search API and has the "Preserve facets"
  // option enabled, and that the Facets module is installed.
  $preserve_facets = !empty($query_plugin->options['preserve_facet_query_args']) && $query_plugin instanceof SearchApiQuery && \Drupal::moduleHandler()
    ->moduleExists('facets');
  if ($preserve_facets) {
    $filter_key = 'f';

    // Attempt to retrieve the facet source to use the actual facets filter
    // parameter as configured by the admin. (Facet source config entities are
    // not always actually saved in the storage, if the admin didn't change
    // their settings.)
    $query = $query_plugin
      ->getSearchApiQuery();
    $display_id = $query
      ->getSearchId(FALSE);
    $facet_source_id = str_replace(':', '__', 'search_api:' . $display_id);
    $facet_source = \Drupal::entityTypeManager()
      ->getStorage('facets_facet_source')
      ->load($facet_source_id);
    if ($facet_source) {
      $filter_key = $facet_source
        ->getFilterKey() ?: 'f';
    }

    // Get the active facet filters from the query parameters.
    $filters = \Drupal::request()->query
      ->get($filter_key, []);

    // Do not iterate over facet filters if the parameter is not an array.
    if (!is_array($filters)) {
      return;
    }

    // Iterate through the facet filters.
    foreach ($filters as $key => $value) {
      if (!is_string($value)) {
        continue;
      }

      // Add a hidden form field for the facet parameter.
      $form["{$filter_key}[{$key}]"] = [
        '#type' => 'hidden',
        '#value' => $value,
      ];
    }
  }
}