Provide better DX for custom integrations using the facet manager

Created on 6 October 2022, about 2 years ago

Problem/Motivation

In a custom code ajax form we are using existing facets, but we are doing the rendering ourselves. So the only thing we are interested in is the updated amount of results after each change.

Since facets uses the url processor by default (and we do not want to change that) we need to set the active filters ourselves, which si psosible with somethling like this:

    // collect $active_filters from form state

    /** @var \Drupal\facets\UrlProcessor\UrlProcessorInterface $urlProcessor */
    $urlProcessor = $facet->getProcessors()['url_processor_handler']->getProcessor();
    $urlProcessor->setActiveFilters($active_filters);
    if (array_key_exists($facet->id(), $active_filters)) {
      $facet->setActiveItems($active_filters[$facet->id()]);
    }
    /** @var \Drupal\facets\FacetManager\DefaultFacetManager $facets_manager */
    $facets_manager->updateResults($facet->getFacetSourceId());
    $facet = $facets_manager->returnBuiltFacet($facet);
    $results = $facet->getResults();

However, this doesn't work because in `alterQuery` the facet manager will re-load the facets using `getFacetsByFacetSourceId`, and our custom set filters get lost.

There does not seem to be a way (probably by design) to set the currently used facets in the manager to provide such integration.

Steps to reproduce

See above.

Proposed resolution

In our case, the problem can be solved by adding a setter/getter for the current facets in the facet manager. A patch is provided.

Remaining tasks

Discuss what would be the best approach for such integrations. Understandably, allowing to set facets directly can result in unexpected behavior (for instance there is not check the facets are from the same source).

User interface changes

None.

API changes

Default facet manager provides a setter/getter.

Data model changes

None.

Feature request
Status

Active

Version

2.0

Component

Code

Created by

🇳🇱Netherlands askibinski

Live updates comments and jobs are added and updated live.
Sign in to follow issues

Comments & Activities

Not all content is available!

It's likely this issue predates Contrib.social: some issue and comment data are missing.

  • 🇧🇪Belgium kwinten-hardies Vlaams-Brabant

    Hi

    Can you provide an example of updating facet fields based on form states with ajax? I am using the FacetsManager class.
    Saying you have a facet id "job_type". and based on that value, the location will change.

    I can't seem to figure it out. My code gives an error "Call to a member function getFacetSourceId() on string"

    <?php
    $facetsource_id = 'search_api:views_page__job_search__page_1';
    $jobDefault = 'Administrator';
            $facets = $this->facetsManager->getFacetsByFacetSourceId($facetsource_id);
            if($jobDefault) {
                $this->facetsManager->setFacets(['job_type' => $jobDefault]);
            }
            $this->facetsManager->updateResults($facetsource_id); // Gives an error in the facet Class "DefaultFacetManager".  "Call to a member function getFacetSourceId() on string"
    ?>

    Above code lives in buildForm method.

    My FacetManager is correctly declared.
    I have also a declaration of "FacetsUrlGenerator". But I have no idea what to do with it.

    How can I retrieve the correct facet values for both job_type and location?
    Thank you.

Production build 0.71.5 2024