Commit 196f96b2 authored by Markus Kalkbrenner's avatar Markus Kalkbrenner Committed by Markus Kalkbrenner
Browse files

Issue #3270731 by mkalkbrenner: "Hide non-narrowing results" leads to empty...

Issue #3270731 by mkalkbrenner: "Hide non-narrowing results" leads to empty facets if "Keep hierarchy parents active" is not selected for hierarchical facets
parent 20455861
Loading
Loading
Loading
Loading
+11 −4
Original line number Diff line number Diff line
@@ -191,10 +191,7 @@ function facets_update_8006() {
 * Resave facets for consistent configuration export.
 */
function facets_update_8007() {
  $facets = Facet::loadMultiple();
  foreach ($facets as $facet) {
    $facet->save();
  }
  // Moved to facets_update_8009().
}

/**
@@ -209,3 +206,13 @@ function facets_update_8008() {
    $facet->save(TRUE);
  }
}

/**
 * Resave facets for consistent configuration export.
 */
function facets_update_8009() {
  $facets = Facet::loadMultiple();
  foreach ($facets as $facet) {
    $facet->save();
  }
}
+0 −66
Original line number Diff line number Diff line
@@ -57,13 +57,6 @@ class DefaultFacetManager {
   */
  protected $facets = [];

  /**
   * An array of all entity ids in the active resultset which are a child.
   *
   * @var string[]
   */
  protected $childIds = [];

  /**
   * The entity storage for facets.
   *
@@ -284,24 +277,6 @@ class DefaultFacetManager {
        $results = $processor->build($facet, $results);
      }

      // Handle hierarchy.
      if ($results && $facet->getUseHierarchy()) {
        $keyed_results = [];
        foreach ($results as $result) {
          $keyed_results[$result->getRawValue()] = $result;
        }

        $parent_groups = $facet->getHierarchyInstance()->getChildIds(array_keys($keyed_results));
        $keyed_results = $this->buildHierarchicalTree($keyed_results, $parent_groups);

        // Remove children from primary level.
        foreach (array_unique($this->childIds) as $child_id) {
          unset($keyed_results[$child_id]);
        }

        $results = array_values($keyed_results);
      }

      // Trigger sort stage.
      $active_sort_processors = [];
      foreach ($facet->getProcessorsByStage(ProcessorInterface::STAGE_SORT) as $processor) {
@@ -451,47 +426,6 @@ class DefaultFacetManager {
    return $this->processBuild($facet);
  }

  /**
   * Builds an hierarchical structure for results.
   *
   * When given an array of results and an array which defines the hierarchical
   * structure, this will build the results structure and set all childs.
   *
   * @param \Drupal\facets\Result\ResultInterface[] $keyed_results
   *   An array of results keyed by id.
   * @param array $parent_groups
   *   An array of 'child id arrays' keyed by their parent id.
   *
   * @return \Drupal\facets\Result\ResultInterface[]
   *   An array of results structured hierarchically.
   */
  protected function buildHierarchicalTree(array $keyed_results, array $parent_groups) {
    foreach ($keyed_results as &$result) {
      $current_id = $result->getRawValue();
      if (isset($parent_groups[$current_id]) && $parent_groups[$current_id]) {
        $child_ids = $parent_groups[$current_id];
        $child_keyed_results = [];
        foreach ($child_ids as $child_id) {
          if (isset($keyed_results[$child_id])) {
            $child_keyed_results[$child_id] = $keyed_results[$child_id];
          }
          else {
            // Children could already be built by Facets Summary manager, if
            // they are, just loading them will suffice.
            $children = $keyed_results[$current_id]->getChildren();
            if (!empty($children[$child_id])) {
              $child_keyed_results[$child_id] = $children[$child_id];
            }
          }
        }
        $result->setChildren($child_keyed_results);
        $this->childIds = array_merge($this->childIds, $child_ids);
      }
    }

    return $keyed_results;
  }

  /**
   * Sort the facet results, and recurse to children to do the same.
   *
+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ class HideNonNarrowingResultProcessor extends ProcessorPluginBase implements Bui

    /** @var \Drupal\facets\Result\ResultInterface $result */
    foreach ($results as $id => $result) {
      if ((($result->getCount() == $result_count) || ($result->getCount() == 0)) && !$result->isActive()) {
      if ((($result->getCount() == $result_count) || ($result->getCount() == 0)) && !$result->isActive() && !$result->hasActiveChildren()) {
        unset($results[$id]);
      }
    }
+97 −0
Original line number Diff line number Diff line
<?php

namespace Drupal\facets\Plugin\facets\processor;

use Drupal\facets\FacetInterface;
use Drupal\facets\Processor\BuildProcessorInterface;
use Drupal\facets\Processor\ProcessorPluginBase;

/**
 * The hierarchy processor transforms the result in a tree.
 *
 * @FacetsProcessor(
 *   id = "hierarchy_processor",
 *   label = @Translation("Build hierarchy tree"),
 *   description = @Translation("Build the tree for facets that use hierarchy.."),
 *   stages = {
 *     "build" = 100,
 *   },
 *   locked = true
 * )
 */
class HierarchyProcessor extends ProcessorPluginBase implements BuildProcessorInterface {

  /**
   * An array of all entity ids in the active resultset which are a child.
   *
   * @var string[]
   */
  protected $childIds = [];
  
  /**
   * {@inheritdoc}
   */
  public function build(FacetInterface $facet, array $results) {
    // Handle hierarchy.
    if ($results && $facet->getUseHierarchy()) {
      $keyed_results = [];
      foreach ($results as $result) {
        $keyed_results[$result->getRawValue()] = $result;
      }

      $parent_groups = $facet->getHierarchyInstance()->getChildIds(array_keys($keyed_results));
      $keyed_results = $this->buildHierarchicalTree($keyed_results, $parent_groups);

      // Remove children from primary level.
      foreach (array_unique($this->childIds) as $child_id) {
        unset($keyed_results[$child_id]);
      }

      $results = array_values($keyed_results);
    }

    return $results;
  }

  /**
   * Builds a hierarchical structure for results.
   *
   * When given an array of results and an array which defines the hierarchical
   * structure, this will build the results structure and set all childs.
   *
   * @param \Drupal\facets\Result\ResultInterface[] $keyed_results
   *   An array of results keyed by id.
   * @param array $parent_groups
   *   An array of 'child id arrays' keyed by their parent id.
   *
   * @return \Drupal\facets\Result\ResultInterface[]
   *   An array of results structured hierarchically.
   */
  protected function buildHierarchicalTree(array $keyed_results, array $parent_groups): array {
    foreach ($keyed_results as &$result) {
      $current_id = $result->getRawValue();
      if (isset($parent_groups[$current_id]) && $parent_groups[$current_id]) {
        $child_ids = $parent_groups[$current_id];
        $child_keyed_results = [];
        foreach ($child_ids as $child_id) {
          if (isset($keyed_results[$child_id])) {
            $child_keyed_results[$child_id] = $keyed_results[$child_id];
          }
          else {
            // Children could already be built by Facets Summary manager, if
            // they are, just loading them will suffice.
            $children = $keyed_results[$current_id]->getChildren();
            if (!empty($children[$child_id])) {
              $child_keyed_results[$child_id] = $children[$child_id];
            }
          }
        }
        $result->setChildren($child_keyed_results);
        $this->childIds = array_merge($this->childIds, $child_ids);
      }
    }

    return $keyed_results;
  }

}