You are here

public function QueryString::buildUrls in Facets 8

Adds urls to the results.

Parameters

\Drupal\facets\FacetInterface $facet: The facet.

\Drupal\facets\Result\ResultInterface[] $results: An array of results.

Return value

\Drupal\facets\Result\ResultInterface[] An array of results with added urls.

Overrides UrlProcessorInterface::buildUrls

File

src/Plugin/facets/url_processor/QueryString.php, line 67

Class

QueryString
Query string URL processor.

Namespace

Drupal\facets\Plugin\facets\url_processor

Code

public function buildUrls(FacetInterface $facet, array $results) {

  // No results are found for this facet, so don't try to create urls.
  if (empty($results)) {
    return [];
  }

  // First get the current list of get parameters.
  $get_params = $this->request->query;

  // When adding/removing a filter the number of pages may have changed,
  // possibly resulting in an invalid page parameter.
  if ($get_params
    ->has('page')) {
    $current_page = $get_params
      ->get('page');
    $get_params
      ->remove('page');
  }

  // Set the url alias from the facet object.
  $this->urlAlias = $facet
    ->getUrlAlias();
  $facet_source_path = $facet
    ->getFacetSource()
    ->getPath();
  $request = $this
    ->getRequestByFacetSourcePath($facet_source_path);
  $requestUrl = $this
    ->getUrlForRequest($facet_source_path, $request);
  $original_filter_params = [];
  foreach ($this
    ->getActiveFilters() as $facet_id => $values) {
    $values = array_filter($values, static function ($it) {
      return $it !== NULL;
    });
    foreach ($values as $value) {
      $original_filter_params[] = $this
        ->getUrlAliasByFacetId($facet_id, $facet
        ->getFacetSourceId()) . ":" . $value;
    }
  }

  /** @var \Drupal\facets\Result\ResultInterface[] $results */
  foreach ($results as &$result) {

    // Reset the URL for each result.
    $url = clone $requestUrl;

    // Sets the url for children.
    if ($children = $result
      ->getChildren()) {
      $this
        ->buildUrls($facet, $children);
    }
    if ($result
      ->getRawValue() === NULL) {
      $filter_string = NULL;
    }
    else {
      $filter_string = $this->urlAlias . $this
        ->getSeparator() . $result
        ->getRawValue();
    }
    $result_get_params = clone $get_params;
    $filter_params = $original_filter_params;

    // If the value is active, remove the filter string from the parameters.
    if ($result
      ->isActive()) {
      foreach ($filter_params as $key => $filter_param) {
        if ($filter_param == $filter_string) {
          unset($filter_params[$key]);
        }
      }
      if ($facet
        ->getUseHierarchy()) {
        $id = $result
          ->getRawValue();

        // Disable child filters.
        foreach ($facet
          ->getHierarchyInstance()
          ->getNestedChildIds($id) as $child_id) {
          $filter_params = array_diff($filter_params, [
            $this->urlAlias . $this
              ->getSeparator() . $child_id,
          ]);
        }
        if ($facet
          ->getEnableParentWhenChildGetsDisabled()) {

          // Enable parent id again if exists.
          $parent_ids = $facet
            ->getHierarchyInstance()
            ->getParentIds($id);
          if (isset($parent_ids[0]) && $parent_ids[0]) {

            // Get the parents children.
            $child_ids = $facet
              ->getHierarchyInstance()
              ->getNestedChildIds($parent_ids[0]);

            // Check if there are active siblings.
            $active_sibling = FALSE;
            if ($child_ids) {
              foreach ($results as $result2) {
                if ($result2
                  ->isActive() && $result2
                  ->getRawValue() != $id && in_array($result2
                  ->getRawValue(), $child_ids)) {
                  $active_sibling = TRUE;
                  continue;
                }
              }
            }
            if (!$active_sibling) {
              $filter_params[] = $this->urlAlias . $this
                ->getSeparator() . $parent_ids[0];
            }
          }
        }
      }
    }
    else {
      if ($filter_string !== NULL) {
        $filter_params[] = $filter_string;
      }
      $parents_and_child_ids = [];
      if ($facet
        ->getUseHierarchy()) {
        $parent_ids = $facet
          ->getHierarchyInstance()
          ->getParentIds($result
          ->getRawValue());
        $child_ids = $facet
          ->getHierarchyInstance()
          ->getNestedChildIds($result
          ->getRawValue());
        $parents_and_child_ids = array_merge($parent_ids, $child_ids);
        if (!$facet
          ->getKeepHierarchyParentsActive()) {

          // If hierarchy is active, unset parent trail and every child when
          // building the enable-link to ensure those are not enabled anymore.
          foreach ($parents_and_child_ids as $id) {
            $filter_params = array_diff($filter_params, [
              $this->urlAlias . $this
                ->getSeparator() . $id,
            ]);
          }
        }
      }

      // Exclude currently active results from the filter params if we are in
      // the show_only_one_result mode.
      if ($facet
        ->getShowOnlyOneResult()) {
        foreach ($results as $result2) {
          if ($result2
            ->isActive()) {
            $id = $result2
              ->getRawValue();
            if (!in_array($id, $parents_and_child_ids)) {
              $active_filter_string = $this->urlAlias . $this
                ->getSeparator() . $id;
              foreach ($filter_params as $key2 => $filter_param2) {
                if ($filter_param2 == $active_filter_string) {
                  unset($filter_params[$key2]);
                }
              }
            }
          }
        }
      }
    }

    // Allow other modules to alter the result url built.
    $event = new QueryStringCreated($result_get_params, $filter_params, $result, $this->activeFilters, $facet);
    $this->eventDispatcher
      ->dispatch(QueryStringCreated::NAME, $event);
    $filter_params = $event
      ->getFilterParameters();
    asort($filter_params, \SORT_NATURAL);
    $result_get_params
      ->set($this->filterKey, array_values($filter_params));
    if ($result_get_params
      ->all() !== [
      $this->filterKey => [],
    ]) {
      $new_url_params = $result_get_params
        ->all();
      if (empty($new_url_params[$this->filterKey])) {
        unset($new_url_params[$this->filterKey]);
      }

      // Facet links should be page-less.
      // See https://www.drupal.org/node/2898189.
      unset($new_url_params['page']);

      // Remove core wrapper format (e.g. render-as-ajax-response) paremeters.
      unset($new_url_params[MainContentViewSubscriber::WRAPPER_FORMAT]);

      // Set the new url parameters.
      $url
        ->setOption('query', $new_url_params);
    }
    $result
      ->setUrl($url);
  }

  // Restore page parameter again. See https://www.drupal.org/node/2726455.
  if (isset($current_page)) {
    $get_params
      ->set('page', $current_page);
  }
  return $results;
}