diff --git a/modules/facets_exposed_filters/src/Plugin/views/filter/FacetsFilter.php b/modules/facets_exposed_filters/src/Plugin/views/filter/FacetsFilter.php index 80f5e9ed716a804aec4e6a2d4d909d5b407a0db1..495c076a71526ffbb53e37f3b95ed5c472a503ed 100644 --- a/modules/facets_exposed_filters/src/Plugin/views/filter/FacetsFilter.php +++ b/modules/facets_exposed_filters/src/Plugin/views/filter/FacetsFilter.php @@ -7,8 +7,10 @@ use Drupal\Core\Block\BlockPluginInterface; use Drupal\Core\Form\FormStateInterface; use Drupal\Core\Form\SubformState; use Drupal\facets\Entity\Facet; +use Drupal\facets\Exception\InvalidProcessorException; use Drupal\facets\FacetInterface; use Drupal\facets\Hierarchy\HierarchyPluginBase; +use Drupal\facets\Processor\PreQueryProcessorInterface; use Drupal\facets\Processor\ProcessorInterface; use Drupal\facets\Processor\SortProcessorInterface; use Drupal\facets\Result\Result; @@ -33,6 +35,13 @@ class FacetsFilter extends FilterPluginBase { */ public $facet_results = []; + /** + * The facet object related to this filter. + * + * @var \Drupal\facets\FacetInterface|null + */ + private ?FacetInterface $facet = NULL; + /** * {@inheritdoc} */ @@ -159,7 +168,6 @@ class FacetsFilter extends FilterPluginBase { if (!empty($active_sort_processors)) { $facet->setResults($this->sortFacetResults($active_sort_processors, $facet->getResults())); } - $facet->setActiveItems(array_values($active_facet_values)); // Store the processed facet so we can access it later (e.g. in an exposed form rendered as a block). facets_exposed_filters_get_processed_facet($this->view->id(), $this->view->current_display, $this->options["id"], $facet); @@ -169,6 +177,14 @@ class FacetsFilter extends FilterPluginBase { $select_element = \Drupal::service('element_info')->getInfo('select'); $this->value = $facet->getActiveItems(); + if (!empty($this->value)) { + $selected_value = array_combine($this->value, $this->value); + $identifier = $this->options['expose']['identifier']; + if (empty($form_state->getUserInput()[$identifier])) { + $form_state->getUserInput()[$identifier] = $selected_value; + } + } + // Store processed results so other modules can use these. $this->facet_results = $facet->getResults(); $form['value'] = [ @@ -237,12 +253,28 @@ class FacetsFilter extends FilterPluginBase { return FALSE; } + /** + * {@inheritdoc} + */ + public function preQuery() { + $facet = $this->getFacet(); + foreach ($facet->getProcessorsByStage(ProcessorInterface::STAGE_PRE_QUERY) as $processor) { + /** @var \Drupal\facets\Processor\PreQueryProcessorInterface $pre_query_processor */ + $pre_query_processor = $facet->getProcessors()[$processor->getPluginDefinition()['id']]; + if (!$pre_query_processor instanceof PreQueryProcessorInterface) { + throw new InvalidProcessorException("The processor {$processor->getPluginDefinition()['id']} has a pre_query definition but doesn't implement the required PreQueryProcessorInterface interface"); + } + $pre_query_processor->preQuery($facet); + } + } + /** * {@inheritdoc} */ public function query() { $facet = $this->getFacet(); $active_values = $this->getActiveFacetValues(); + $facet->setActiveItems($active_values); $qtpm = \Drupal::service('plugin.manager.facets.query_type'); @@ -514,7 +546,10 @@ class FacetsFilter extends FilterPluginBase { /** * Helper function to retrieve the representing facet. */ - private function getFacet() { + private function getFacet(): FacetInterface { + if ($this->facet instanceof FacetInterface) { + return $this->facet; + } $facet = Facet::create([ 'id' => $this->options["field"], 'field_identifier' => $this->configuration["search_api_field_identifier"], @@ -538,7 +573,8 @@ class FacetsFilter extends FilterPluginBase { ]); } } - return $facet; + $this->facet = $facet; + return $this->facet; } /** @@ -548,22 +584,24 @@ class FacetsFilter extends FilterPluginBase { * to retrieve the active filters from the request ourself. */ private function getActiveFacetValues() { + $active_values = $this->facet->getActiveItems(); + // Reset button in ajax request. We probably want a better way to detect if this was clicked. if(isset($_GET["reset"])) { - return []; + return $active_values; } $exposed = $this->view->getExposedInput(); if (!isset($exposed[$this->options["expose"]["identifier"]])) { - return []; + return $active_values; } $enabled = $exposed[$this->options["expose"]["identifier"]]; if ($enabled == 'All') { - return []; + return $active_values; } elseif (!is_array($enabled)) { $enabled = [$enabled]; } - return $enabled; + return array_values(array_unique([...$active_values, ...$enabled])); } /**