Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save andybroomfield/0b17ba2a48769f6aa031ca9c12652088 to your computer and use it in GitHub Desktop.

Select an option

Save andybroomfield/0b17ba2a48769f6aa031ca9c12652088 to your computer and use it in GitHub Desktop.
Patch for localgov_directories better exposed filter support
diff --git a/localgov_directories.module b/localgov_directories.module
index 8acc740..1403fe9 100644
--- a/localgov_directories.module
+++ b/localgov_directories.module
@@ -57,6 +57,10 @@ function localgov_directories_theme() {
'checkboxes__localgov_directories_facets' => [
'base hook' => 'checkboxes',
],
+ 'bef_checkboxes_directory_facets' => [
+ 'render element' => 'element',
+ 'base_hook' => 'bef_checkboxes',
+ ],
];
}
@@ -321,3 +325,26 @@ function localgov_directories_leaflet_map_view_style_alter(&$js_settings, $leafl
function localgov_directories_facets_search_api_query_type_mapping_alter($backend_plugin_id, array &$query_types) {
$query_types['localgov_directories'] = 'localgov_directories_query_type';
}
+
+/**
+ * Implements hook_template_preprocess_bef_checkboxes_directory_facets().
+ */
+function template_preprocess_bef_checkboxes_directory_facets(array &$variables): void {
+ $element = $variables['element'];
+ $facet_groups = $element['#localgov_directory_facet_groups'];
+ $facet_group_elements = [];
+
+ // Split up the facet checkboxes into groups based on the facet group.
+ foreach ($facet_groups as $key => $values) {
+ $facet_group_elements[$key] = [
+ '#type' => 'fieldset',
+ '#title' => $values['title'],
+ '#weight' => $values['weight'],
+ ];
+ $options = array_keys($values['items']);
+ $facet_group_elements[$key]['children'] = array_map(function ($item) use ($element) {
+ return $element[$item];
+ }, $options);
+ }
+ $variables['localgov_directory_facet_groups'] = $facet_group_elements;
+}
diff --git a/src/DirectoryExtraFieldDisplay.php b/src/DirectoryExtraFieldDisplay.php
index 3c36e36..489bfe5 100644
--- a/src/DirectoryExtraFieldDisplay.php
+++ b/src/DirectoryExtraFieldDisplay.php
@@ -23,6 +23,7 @@ use Drupal\localgov_directories\Entity\LocalgovDirectoriesFacetsType;
use Drupal\node\NodeInterface;
use Drupal\views\Views;
use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\RequestStack;
/**
* Adds views display for the directory channel.
@@ -73,6 +74,13 @@ class DirectoryExtraFieldDisplay implements ContainerInjectionInterface, Trusted
*/
protected $routeMatch;
+ /**
+ * The request stack.
+ *
+ * @var \Symfony\Component\HttpFoundation\RequestStack
+ */
+ protected $requestStack;
+
/**
* DirectoryExtraFieldDisplay constructor.
*
@@ -88,14 +96,17 @@ class DirectoryExtraFieldDisplay implements ContainerInjectionInterface, Trusted
* Form Builder.
* @param \Drupal\Core\Routing\RouteMatchInterface $route_match
* Current route match.
+ * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
+ * The request stack.
*/
- public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityRepositoryInterface $entity_repository, EntityFieldManagerInterface $entity_field_manager, BlockManagerInterface $plugin_manager_block, FormBuilderInterface $form_builder, RouteMatchInterface $route_match) {
+ public function __construct(EntityTypeManagerInterface $entity_type_manager, EntityRepositoryInterface $entity_repository, EntityFieldManagerInterface $entity_field_manager, BlockManagerInterface $plugin_manager_block, FormBuilderInterface $form_builder, RouteMatchInterface $route_match, RequestStack $request_stack) {
$this->entityTypeManager = $entity_type_manager;
$this->entityRepository = $entity_repository;
$this->entityFieldManager = $entity_field_manager;
$this->pluginBlockManager = $plugin_manager_block;
$this->formBuilder = $form_builder;
$this->routeMatch = $route_match;
+ $this->requestStack = $request_stack;
}
/**
@@ -108,7 +119,8 @@ class DirectoryExtraFieldDisplay implements ContainerInjectionInterface, Trusted
$container->get('entity_field.manager'),
$container->get('plugin.manager.block'),
$container->get('form_builder'),
- $container->get('current_route_match')
+ $container->get('current_route_match'),
+ $container->get('request_stack'),
);
}
@@ -353,7 +365,26 @@ class DirectoryExtraFieldDisplay implements ContainerInjectionInterface, Trusted
// This is usually on a channel node. If so remove facets not active on
// channel.
$active_facets = NULL;
- if (($channel = $this->routeMatch->getParameter('node'))
+ $route_name = $this->routeMatch->getRouteName();
+ $channel = match($route_name) {
+
+ // Embdeded on a page.
+ 'entity.node.canonical' => $this->routeMatch->getParameter('node'),
+
+ // Handle views ajax request.
+ 'views.ajax' => call_user_func(function () {
+ $query_str = $this->requestStack->getCurrentRequest()->getQueryString();
+ parse_str($query_str, $query);
+ if ($query['view_name'] == 'localgov_directory_channel' && $nid = intval($query['view_args'])) {
+ return $this->entityTypeManager->getStorage('node')->load($nid);
+ }
+ return NULL;
+ }),
+
+ // No valid channel found.
+ default => NULL,
+ };
+ if (!is_null($channel)
&& $channel instanceof NodeInterface
&& $channel->bundle() == 'localgov_directory'
) {
diff --git a/src/Plugin/better_exposed_filters/filter/DirectoryFacetsCheckboxes.php b/src/Plugin/better_exposed_filters/filter/DirectoryFacetsCheckboxes.php
new file mode 100644
index 0000000..8acca77
--- /dev/null
+++ b/src/Plugin/better_exposed_filters/filter/DirectoryFacetsCheckboxes.php
@@ -0,0 +1,83 @@
+<?php
+
+namespace Drupal\localgov_directories\Plugin\better_exposed_filters\filter;
+
+use Drupal\Core\Form\FormStateInterface;
+use Drupal\better_exposed_filters\Plugin\better_exposed_filters\filter\RadioButtons;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\DependencyInjection\ClassResolverInterface;
+use Drupal\localgov_directories\DirectoryExtraFieldDisplay;
+
+/**
+ * Localgov directories facets widget implementation.
+ *
+ * @BetterExposedFiltersFilterWidget(
+ * id = "localgov_directory_facets",
+ * label = @Translation("Localgov directory facets"),
+ * )
+ */
+class DirectoryFacetsCheckboxes extends RadioButtons implements ContainerFactoryPluginInterface {
+
+ /**
+ * Class resolver service.
+ *
+ * @var \Drupal\Core\DependencyInjection\ClassResolverInterface
+ */
+ protected $classResolver;
+
+ /**
+ * Constructs a DirectoryFacetsCheckboxes object.
+ *
+ * @param array $configuration
+ * A configuration array containing information about the plugin instance.
+ * @param string $plugin_id
+ * The plugin ID for the plugin instance.
+ * @param mixed $plugin_definition
+ * The plugin implementation definition.
+ * @param Drupal\Core\DependencyInjection\ClassResolverInterface $class_resolver
+ * Class resolver service.
+ */
+ public function __construct(array $configuration, string $plugin_id, $plugin_definition, ClassResolverInterface $class_resolver) {
+ parent::__construct($configuration, $plugin_id, $plugin_definition);
+ $this->classResolver = $class_resolver;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): DirectoryFacetsCheckboxes {
+ return new static(
+ $configuration,
+ $plugin_id,
+ $plugin_definition,
+ $container->get('class_resolver'),
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function exposedFormAlter(array &$form, FormStateInterface $form_state): void {
+ /** @var \Drupal\views\Plugin\views\filter\FilterPluginBase $filter */
+ $filter = $this->handler;
+ // Form element is designated by the element ID which is user-
+ // configurable.
+ $field_id = $filter->options['is_grouped'] ? $filter->options['group_info']['identifier'] : $filter->options['expose']['identifier'];
+
+ parent::exposedFormAlter($form, $form_state);
+
+ if (!empty($form[$field_id]['#options'])) {
+
+ // Use the groupDirFacetItems from the DirectoryExtraFieldDisplay class.
+ // This is the same as the facets block, which will group and filter
+ // the avalible facets to the relevant directory channel.
+ $grouped_items = $this->classResolver
+ ->getInstanceFromDefinition(DirectoryExtraFieldDisplay::class)
+ ->groupDirFacetItems($form[$field_id]['#options']);
+ $form[$field_id]['#localgov_directory_facet_groups'] = $grouped_items;
+ $form[$field_id]['#theme'] = 'bef_checkboxes_directory_facets';
+ }
+ }
+
+}
diff --git a/templates/bef-checkboxes-directory-facets.html.twig b/templates/bef-checkboxes-directory-facets.html.twig
new file mode 100644
index 0000000..7390233
--- /dev/null
+++ b/templates/bef-checkboxes-directory-facets.html.twig
@@ -0,0 +1,13 @@
+{% set classes = [
+ 'form-checkboxes',
+ 'bef-checkboxes',
+ 'bef-checkboxes-directory-facets',
+ show_select_all_none ? 'bef-select-all-none',
+ show_select_all_none_nested ? 'bef-select-all-none-nested',
+ display_inline ? 'form--inline'
+] %}
+<div{{ wrapper_attributes.addClass(classes) }}>
+ {% for facet_group in localgov_directory_facet_groups %}
+ {{ facet_group }}
+ {% endfor %}
+</div>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment