Commit 588a6b4b authored by Markus Kalkbrenner's avatar Markus Kalkbrenner Committed by Markus Kalkbrenner
Browse files

Issue #3268891 by mkalkbrenner: Combined facets edge cases

parent 75f40c0b
Loading
Loading
Loading
Loading
+14 −5
Original line number Diff line number Diff line
@@ -792,12 +792,21 @@ class Facet extends ConfigEntityBase implements FacetInterface {
  /**
   * {@inheritdoc}
   */
  public function getResultsKeyedByRawValue() {
    $results = [];
    foreach ($this->results as $result) {
      $results[$result->getRawValue()] = $result;
  public function getResultsKeyedByRawValue($results = NULL) {
    if ($results === NULL) {
      $results = $this->results;
    }

    $keyed_results = [];

    foreach ($results as $result) {
      $keyed_results[$result->getRawValue()] = $result;
      if ($children = $result->getChildren()) {
        $keyed_results = $keyed_results + $this->getResultsKeyedByRawValue($children);
      }
    }
    return $results;

    return $keyed_results;
  }

  /**
+6 −2
Original line number Diff line number Diff line
@@ -183,12 +183,16 @@ interface FacetInterface extends ConfigEntityInterface {
  public function getResults();

  /**
   * Returns the result for the facet.
   * Returns the flat result for the facet keyed by their raw values.
   *
   * @param \Drupal\facets\Result\ResultInterface[]|null $results
   *   The results to be converted into a flat keyed by raw value array. If
   *   not provided the entire current result set of the facet will be used.
   *
   * @return \Drupal\facets\Result\ResultInterface[]
   *   The results of the facet.
   */
  public function getResultsKeyedByRawValue();
  public function getResultsKeyedByRawValue($results = NULL);

  /**
   * Sets the results for the facet.
+111 −62
Original line number Diff line number Diff line
@@ -76,7 +76,14 @@ class DefaultFacetManager {
   *
   * @var \Drupal\facets\FacetInterface[]
   */
  protected $processedFacets;
  protected $processedFacets = [];

  /**
   * A static cache of already built facets.
   *
   * @var \Drupal\facets\FacetInterface[]
   */
  protected $builtFacets = [];

  /**
   * Constructs a new instance of the DefaultFacetManager.
@@ -232,26 +239,23 @@ class DefaultFacetManager {
  }

  /**
   * Builds a facet and returns it as a renderable array.
   *
   * This method delegates to the relevant plugins to render a facet, it calls
   * out to a widget plugin to do the actual rendering when results are found.
   * When no results are found it calls out to the correct empty result plugin
   * to build a render array.
   * Builds a facet.
   *
   * Before doing any rendering, the processors that implement the
   * BuildProcessorInterface enabled on this facet will run.
   * This method delegates to the relevant plugins in Build stage, the
   * processors that implement the  BuildProcessorInterface enabled on this
   * facet will run.
   *
   * @param \Drupal\facets\FacetInterface $facet
   *   The facet we should build.
   *
   * @return array
   *   Facet render arrays.
   * @return \Drupal\facets\FacetInterface
   *   The built Facet.
   *
   * @throws \Drupal\facets\Exception\InvalidProcessorException
   *   Throws an exception when an invalid processor is linked to the facet.
   */
  public function build(FacetInterface $facet) {
  protected function processBuild(FacetInterface $facet) {
    if (!isset($this->builtFacets[$facet->getFacetSourceId()][$facet->id()])) {
      // Immediately initialize the facets if they are not initiated yet.
      $this->initFacets();

@@ -261,16 +265,6 @@ class DefaultFacetManager {
      // static cache.
      $facet = $this->facets[$facet->id()];

    if ($facet->getOnlyVisibleWhenFacetSourceIsVisible()) {
      // Block rendering and processing should be stopped when the facet source
      // is not available on the page. Returning an empty array here is enough
      // to halt all further processing.
      $facet_source = $facet->getFacetSource();
      if (is_null($facet_source) || !$facet_source->isRenderedInCurrentRequest()) {
        return [];
      }
    }

      // For clarity, process facets is called each build.
      // The first facet therefor will trigger the processing. Note that
      // processing is done only once, so repeatedly calling this method will not
@@ -321,6 +315,45 @@ class DefaultFacetManager {

      $facet->setResults($results);

      $this->builtFacets[$facet->getFacetSourceId()][$facet->id()] = $facet;
    }

    return $this->builtFacets[$facet->getFacetSourceId()][$facet->id()];
  }

  /**
   * Builds a facet and returns it as a renderable array.
   *
   * This method delegates to the relevant plugins to render a facet, it calls
   * out to a widget plugin to do the actual rendering when results are found.
   * When no results are found it calls out to the correct empty result plugin
   * to build a render array.
   *
   * Before doing any rendering, the processors that implement the
   * BuildProcessorInterface enabled on this facet will run.
   *
   * @param \Drupal\facets\FacetInterface $facet
   *   The facet we should build.
   *
   * @return array
   *   Facet render arrays.
   *
   * @throws \Drupal\facets\Exception\InvalidProcessorException
   *   Throws an exception when an invalid processor is linked to the facet.
   */
  public function build(FacetInterface $facet) {
    $facet = $this->processBuild($facet);

    if ($facet->getOnlyVisibleWhenFacetSourceIsVisible()) {
      // Block rendering and processing should be stopped when the facet source
      // is not available on the page. Returning an empty array here is enough
      // to halt all further processing.
      $facet_source = $facet->getFacetSource();
      if (is_null($facet_source) || !$facet_source->isRenderedInCurrentRequest()) {
        return [];
      }
    }

    // We include this build even if empty, it may contain attached libraries.
    /** @var \Drupal\facets\Widget\WidgetPluginInterface $widget */
    $widget = $facet->getWidgetInstance();
@@ -369,7 +402,7 @@ class DefaultFacetManager {
  }

  /**
   * Updates all facets of a given facet source with the results.
   * Updates all facets of a given facet source with the raw results.
   *
   * @param string $facetsource_id
   *   The facet source ID of the currently processed facet.
@@ -377,6 +410,10 @@ class DefaultFacetManager {
  public function updateResults($facetsource_id) {
    $facets = $this->getFacetsByFacetSourceId($facetsource_id);
    if ($facets) {
      // clear the caches of processed results.
      unset($this->processedFacets[$facetsource_id]);
      unset($this->builtFacets[$facetsource_id]);

      /** @var \drupal\facets\FacetSource\FacetSourcePluginInterface $facet_source_plugin */
      $facet_source_plugin = $this->facetSourcePluginManager->createInstance($facetsource_id);
      $facet_source_plugin->fillFacetsWithResults($facets);
@@ -388,8 +425,7 @@ class DefaultFacetManager {
   *
   * Returns one of the processed facets, this is a facet with filled results.
   * Keep in mind that if you want to have the facet's build processor executed,
   * there needs to be an extra call to the FacetManager::build with the facet
   * returned here as argument.
   * call returnBuiltFacet() instead.
   *
   * @param \Drupal\facets\FacetInterface $facet
   *   The facet to process.
@@ -402,6 +438,19 @@ class DefaultFacetManager {
    return !empty($this->facets[$facet->id()]) ? $this->facets[$facet->id()] : NULL;
  }

  /**
   * Returns one of the built facets.
   *
   * @param \Drupal\facets\FacetInterface $facet
   *   The facet to process.
   *
   * @return \Drupal\facets\FacetInterface
   *   The built facet.
   */
  public function returnBuiltFacet(FacetInterface $facet) {
    return $this->builtFacets[$facet->id()] ?? $this->processBuild($facet);
  }

  /**
   * Builds an hierarchical structure for results.
   *
+1 −1
Original line number Diff line number Diff line
@@ -147,7 +147,7 @@ class CombineFacetProcessor extends ProcessorPluginBase implements BuildProcesso
    foreach ($enabled_combinations as $facet_id => $settings) {
      /** @var \Drupal\facets\Entity\Facet $current_facet */
      $current_facet = $this->facetStorage->load($facet_id);
      $current_facet = $this->facetsManager->returnProcessedFacet($current_facet);
      $current_facet = $this->facetsManager->returnBuiltFacet($current_facet);

      switch ($settings['mode']) {
        case 'union':
+1 −1
Original line number Diff line number Diff line
@@ -173,7 +173,7 @@ class DependentFacetProcessor extends ProcessorPluginBase implements BuildProces

      /** @var \Drupal\facets\Entity\Facet $current_facet */
      $current_facet = $this->facetStorage->load($facet_id);
      $current_facet = $this->facetsManager->returnProcessedFacet($current_facet);
      $current_facet = $this->facetsManager->returnBuiltFacet($current_facet);

      if ($condition_settings['condition'] == 'not_empty') {
        $return = !empty($current_facet->getActiveItems());
Loading