Score:1

Search API + Facets: Overwrite facet output and conditionally alter query condition based on active filter

kr flag

I have a date field on hundreds of nodes indexed. I created a facet for the date field but it displays all dates available (ew). Instead, we'd like a filter for "Available Now" nodes and "Available in Future" nodes.

Facet Solution: create a custom processor to replace the facet results (hundreds of timestamps) with "Available Now" and "Available in the Future".

/**
 * Provides a processor for Availability.
 *
 * @FacetsProcessor(
 *   id = "availability_processor",
 *   label = @Translation("Availability Processor"),
 *   description = @Translation("Now vs Future Availability"),
 *   stages = {
 *     "build" = 14
 *   }
 * )
 */
class DateProcessorHandler extends UrlProcessorHandler implements BuildProcessorInterface {

  /**
   * {@inheritdoc}
   */
  public function build(FacetInterface $facet, array $results) {
    /** @var \Drupal\facets\Utility\FacetsUrlGenerator $url_generator */
    $url_generator = \Drupal::service('facets.utility.url_generator');

    /** @var ResultInterface $now_result */
    $now_result = new Result($facet, 'now', 'Available Now', 1);
    $now_url = $url_generator->getUrl([$facet->id() => ['now']]);
    $now_result->setUrl($now_url);

    /** @var ResultInterface $future_result */
    $future_result = new Result($facet, 'future', 'Available in the Future', 1);
    $future_url = $url_generator->getUrl([$facet->id() => ['future']]);
    $future_result->setUrl($future_url);

    $new_results = [$now_result, $future_result];
    $facet->setResults($new_results);

    return $new_results;
  }
}

Works great so far; links on the facet add and remove the "now" and "future" url parameters as expected.

However, the results show 0. I tried subscribing to SearchApiEvents::QUERY_PRE_EXECUTE and altering the query to modify the condition:

protected function alterExploreQuery(QueryPreExecuteEvent $query_event) {

  $availability_active_facet = ?????

  $now = \Drupal::service('datetime.time')->getRequestTime();
  $operator = $availability_active_facet === 'now' ? '=<' : '>';
  $query->getConditionGroup()->addCondition('field_date', $now, $operator);
}

This event is fired long before any processors set the active facet items so how do I get the active facet value?

Also, is there any way to output the "Available Now/Future" links in place of dates besides using a custom processor? Reason I ask, the custom processor shows up as an option on all facets, not just the date one I want it to.

mangohost

Post an answer

Most people don’t grasp that asking a lot of questions unlocks learning and improves interpersonal bonding. In Alison’s studies, for example, though people could accurately recall how many questions had been asked in their conversations, they didn’t intuit the link between questions and liking. Across four studies, in which participants were engaged in conversations themselves or read transcripts of others’ conversations, people tended not to realize that question asking would influence—or had influenced—the level of amity between the conversationalists.