You are here

function filter_harmonizer_page_attachments in Views Filter Harmonizer 1.0.x

Same name and namespace in other branches
  1. 8 filter_harmonizer.module \filter_harmonizer_page_attachments()

Implements hook_page_attachments().

This is here to implement the feature that reflects the regular filter choice on the browser address bar, using contextual filters, rather than the "?FIELD_NAME1=VALUE1&FIELD_NAME2=VALUE2" format.

File

./filter_harmonizer.module, line 268
filter_harmonizer.module

Code

function filter_harmonizer_page_attachments(array &$attachments) {
  global $filter_harmonizer_filter_pairs;

  // This is only set if there is a View active on the current page.
  if (empty($filter_harmonizer_filter_pairs)) {
    return;
  }
  if (!Drupal::config('filter_harmonizer.settings')
    ->get('filter_harmonizer_regular_filter_values_in_address_bar')) {
    return;
  }

  // If an (exposed) regular filter was submitted, visually reflect that in the
  // browser address bar.
  $request = Drupal::request();
  $route_path = RouteMatch::createFromRequest($request)
    ->getRouteObject()
    ->getPath();
  $qs = urldecode($request
    ->getQueryString());
  foreach ($filter_harmonizer_filter_pairs as $displays) {
    foreach ($displays as $filters) {
      $arg_values = [];
      $regular_filter_count = 0;
      foreach ($filters as $field_name => $filter_pair) {
        if (isset($filter_pair['regular'])) {
          $regular_filter_count++;
        }

        // If regular filter is empty, take the contextual value (or 'all').
        $arg_values[$field_name] = isset($filter_pair['regular']['value']) ? isset($filter_pair['regular']['stringified']) ? $filter_pair['regular']['stringified'] : $filter_pair['contextual']['exception'] : (isset($filter_pair['contextual']['argument']) ? $filter_pair['contextual']['argument'] : $filter_pair['contextual']['exception']);
      }
      if (!$regular_filter_count) {

        // If we have no active regular filters on this display, then we
        // don't have to update the URL path.
        continue;
      }

      // If the number of /{arg} occurrences in $route_path is not equal to the
      // number of $arg_values we can move to the next display.
      if ($match_count = preg_match_all('/\\/{[^\\/.]+}/', $route_path, $matches)) {
        $matches = reset($matches);

        // used below
      }
      if ($match_count != count($arg_values)) {
        continue;
      }
      $path = $route_path;

      // Now substitute URL, but don't add superfluous trailing "/all"'s.
      // It is assumed that contextual arguments appear in order on the URL.
      // Start at the rear.
      $i = count($arg_values) - 1;
      foreach (array_reverse($arg_values) as $field_name => $value) {
        if (empty($done_exc) && $value == $filters[$field_name]['contextual']['exception']) {

          // Avoid trailing "/all". Wipe the arg.
          $path = str_replace($matches[$i], '', $path);
        }
        else {

          // A non-trailing /all or "normal" value: replace it. Keep the '/'.
          $done_exc = TRUE;
          $path = str_replace($matches[$i], "/{$value}", $path);
        }

        // The Views module appends the regular filter values as rather ugly
        // query-parameters. Example:  ?field_size_value[]=XL
        // These query parameters are no longer required because we've just
        // put the equivalent values in the URL as contextual arguments.
        if (isset($filters[$field_name]['regular'])) {
          $field_alias = $filters[$field_name]['regular']['alias'];
          $pattern = '/' . $field_alias . '\\[.*\\]=.+[&]?/';

          // Remove the query parameter(s) from the query string.
          $qs = preg_replace($pattern, '', $qs);
        }
        $i--;
      }
    }
  }
  if (isset($path) && $path !== $route_path) {
    $path_plus_qs = empty($qs) ? $path : $path . '?' . $qs;
    $attachments['#attached']['drupalSettings']['browser_url'] = $request
      ->getBasePath() . $path_plus_qs;

    // Let's not forget to include the few lines of JS that make this happen!
    $attachments['#attached']['library'][] = 'filter_harmonizer/filter_harmonizer';
  }
}