Created
August 4, 2025 08:57
-
-
Save andybroomfield/0b17ba2a48769f6aa031ca9c12652088 to your computer and use it in GitHub Desktop.
Patch for localgov_directories better exposed filter support
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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