From 4f20f692e1193ae4ce61edb0406d49866d6b2ae9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hern=C3=A2ni=20Borges=20de=20Freitas?= Date: Tue, 5 Jan 2021 16:04:01 +0000 Subject: [PATCH] SDT-151: POC for contextual filters. --- src/EventSubscriber/QuerySubscriber.php | 44 ++++++++++++++++++- src/ListPresetFilter.php | 32 +++++++++++++- src/ListPresetFiltersBuilder.php | 2 +- .../facets/widget/ListPagesWidgetBase.php | 1 + .../facets/widget/MultiselectWidget.php | 21 +++++++++ 5 files changed, 97 insertions(+), 3 deletions(-) diff --git a/src/EventSubscriber/QuerySubscriber.php b/src/EventSubscriber/QuerySubscriber.php index 2ae02dc7..23c68821 100644 --- a/src/EventSubscriber/QuerySubscriber.php +++ b/src/EventSubscriber/QuerySubscriber.php @@ -4,6 +4,7 @@ namespace Drupal\oe_list_pages\EventSubscriber; +use Drupal\Core\Field\EntityReferenceFieldItemListInterface; use Drupal\facets\FacetInterface; use Drupal\facets\FacetManager\DefaultFacetManager; use Drupal\facets\QueryType\QueryTypePluginManager; @@ -179,6 +180,27 @@ protected function processFacetActiveValues(array $facets, array $preset_filter_ return $facets_by_filter; } + /** + * Get original field name from facet config. + * + * @param \Drupal\facets\Entity\FacetInterface $facet + * The facet. + * + * @return string|null + * The field name if found. + */ + protected function getFieldName(FacetInterface $facet) : ?string { + $field = $facet->getFacetSource()->getIndex()->getField($facet->getFieldIdentifier()); + $field_name = $field->getOriginalFieldIdentifier(); + $property_path = $field->getPropertyPath(); + $parts = explode(':', $property_path); + if (count($parts) > 1) { + $field_name = $parts[0]; + } + + return $field_name; + } + /** * Applies the preset filter values onto the facet. * @@ -191,7 +213,27 @@ protected function processFacetActiveValues(array $facets, array $preset_filter_ * The preset values. */ protected function applyPresetFilterValues(FacetInterface $facet, ListPresetFilter $preset_filter): void { - $facet->setActiveItems($preset_filter->getValues()); + + if ($preset_filter->getType() == 'contextual') { + /** @var \Drupal\node\NodeInterface $current_node */ + $current_node = \Drupal::routeMatch()->getParameter('node'); + $field_name = $this->getFieldName($facet); + $field = $current_node->get($field_name); + $field_definition = $field->getFieldDefinition(); + $values = []; + /* @todo create a plugin type MultiSelectFilterFieldPlugin */ + if (in_array(EntityReferenceFieldItemListInterface::class, class_implements($field_definition->getClass()))) { + $field_value = $current_node->get($field_name)->getValue(); + $values = array_map(function ($value) { + return $value['target_id']; + }, $field_value); + } + } + else { + $values = $preset_filter->getValues(); + } + + $facet->setActiveItems($values); if ($preset_filter->getOperator() === ListPresetFilter::NOT_OPERATOR) { $facet->setQueryOperator(ListPresetFilter::AND_OPERATOR); $facet->setExclude(TRUE); diff --git a/src/ListPresetFilter.php b/src/ListPresetFilter.php index a1e4dcc3..43decdbf 100644 --- a/src/ListPresetFilter.php +++ b/src/ListPresetFilter.php @@ -36,6 +36,13 @@ class ListPresetFilter { */ protected $values = []; + /** + * The type. + * + * @var string + */ + protected $type; + /** * ListPresetFilter constructor. * @@ -45,11 +52,14 @@ class ListPresetFilter { * The operator. * @param string $operator * The operator. + * @param string $type + * The type. */ - public function __construct(string $facet_id, array $values, string $operator = self::OR_OPERATOR) { + public function __construct(string $facet_id, array $values, string $operator = self::OR_OPERATOR, string $type = 'static') { $this->facetId = $facet_id; $this->operator = $operator; $this->values = $values; + $this->type = $type; } /** @@ -126,4 +136,24 @@ public static function getOperators(): array { ]; } + /** + * Gets the type. + * + * @return string + * The type. + */ + public function getType(): string { + return $this->type; + } + + /** + * Sets the type. + * + * @param string $type + * The type. + */ + public function setType(string $type): void { + $this->type = $type; + } + } diff --git a/src/ListPresetFiltersBuilder.php b/src/ListPresetFiltersBuilder.php index 61f44a82..34bbc3c6 100644 --- a/src/ListPresetFiltersBuilder.php +++ b/src/ListPresetFiltersBuilder.php @@ -410,7 +410,7 @@ public function setDefaultValueSubmit(array &$form, FormStateInterface $form_sta $widget = $facet->getWidgetInstance(); $preset_filter = $widget->prepareDefaultFilterValue($facet, $current_filters[$filter_id], $subform_state); - $current_filters[$filter_id] = new ListPresetFilter($facet_id, $preset_filter['values'], $preset_filter['operator']); + $current_filters[$filter_id] = new ListPresetFilter($facet_id, $preset_filter['values'], $preset_filter['operator'], $preset_filter['type']); // Set the current filters on the form state so they can be used elsewhere. static::setListSourceCurrentFilterValues($form_state, $list_source, $current_filters); diff --git a/src/Plugin/facets/widget/ListPagesWidgetBase.php b/src/Plugin/facets/widget/ListPagesWidgetBase.php index 90a6582a..093d7739 100644 --- a/src/Plugin/facets/widget/ListPagesWidgetBase.php +++ b/src/Plugin/facets/widget/ListPagesWidgetBase.php @@ -34,6 +34,7 @@ public function prepareValueForUrl(FacetInterface $facet, array &$form, FormStat */ public function prepareDefaultFilterValue(FacetInterface $facet, array $form, FormStateInterface $form_state): array { return [ + 'type' => 'static', 'operator' => ListPresetFilter::OR_OPERATOR, 'values' => $this->prepareValueForUrl($facet, $form, $form_state), ]; diff --git a/src/Plugin/facets/widget/MultiselectWidget.php b/src/Plugin/facets/widget/MultiselectWidget.php index edcc0592..009f9b00 100644 --- a/src/Plugin/facets/widget/MultiselectWidget.php +++ b/src/Plugin/facets/widget/MultiselectWidget.php @@ -100,6 +100,19 @@ public function buildDefaultValueForm(array $form, FormStateInterface $form_stat '#title' => $this->t('Operator'), ]; + $filter_type_options = [ + 'static' => $this->t('Static'), + 'contextual' => $this->t('Contextual'), + ]; + + $form['oe_list_pages_filter_type'] = [ + '#type' => 'radios', + '#weight' => -10, + '#options' => $filter_type_options, + '#default_value' => !empty($preset_filter) && !empty($preset_filter->getType()) ? $preset_filter->getType() : 'static', + '#title' => $this->t('Filter type'), + ]; + $form[$facet->id()] = [ '#type' => 'multivalue', '#title' => $facet->getName(), @@ -208,6 +221,8 @@ public function buildDefaultValueForm(array $form, FormStateInterface $form_stat /** * {@inheritdoc} + * + * @SuppressWarnings(PHPMD.CyclomaticComplexity) */ public function getDefaultValuesLabel(FacetInterface $facet, ListSourceInterface $list_source, ListPresetFilter $filter): string { $field_definition = $this->getFieldDefinition($facet, $list_source); @@ -215,6 +230,11 @@ public function getDefaultValuesLabel(FacetInterface $facet, ListSourceInterface $filter_value = $filter->getValues(); $filter_operators = ListPresetFilter::getOperators(); + $filter_type = $filter->getType(); + if ($filter_type === 'contextual') { + return $filter_operators[$filter->getOperator()] . ': ' . $this->t('Contextual value'); + } + if (in_array(EntityReferenceFieldItemListInterface::class, class_implements($field_definition->getClass()))) { $entity_storage = $this->entityTypeManager->getStorage($field_definition->getSetting('target_type')); $values = []; @@ -330,6 +350,7 @@ public function prepareDefaultFilterValue(FacetInterface $facet, array $form, Fo $operator = $form_state->getValue('oe_list_pages_filter_operator'); return [ + 'type' => $form_state->getValue('oe_list_pages_filter_type'), 'operator' => $operator, 'values' => $values, ];