selectify-1.0.3/src/Form/SelectifySettingsForm.php

src/Form/SelectifySettingsForm.php
<?php

namespace Drupal\selectify\Form;

use Drupal\Core\Config\Config;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Config\TypedConfigManagerInterface;
use Drupal\Core\Form\ConfigFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\views\Views;

/**
 * Configure settings for Selectify Radio/Checkbox & Views Filters.
 */
class SelectifySettingsForm extends ConfigFormBase {

  /**
   * The messenger service.
   *
   * @var \Drupal\Core\Messenger\MessengerInterface
   */
  protected $messenger;

  /**
   * The config factory.
   *
   * @var \Drupal\Core\Config\ConfigFactoryInterface
   */
  protected $configFactory;

  /**
   * Constructs a new SelectifySettingsForm object.
   *
   * @param \Drupal\Core\Config\ConfigFactoryInterface $config_factory
   *   The config factory service.
   * @param \Drupal\Core\Config\TypedConfigManagerInterface $typed_config_manager
   *   The typed config manager service.
   * @param \Drupal\Core\Messenger\MessengerInterface $messenger
   *   The messenger service.
   */
  public function __construct(
    ConfigFactoryInterface $config_factory,
    TypedConfigManagerInterface $typed_config_manager,
    MessengerInterface $messenger,
  ) {
    parent::__construct($config_factory, $typed_config_manager);
    $this->messenger = $messenger;
    $this->configFactory = $config_factory;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container): self {
    return new static(
      $container->get('config.factory'),
      $container->get('config.typed'),
      $container->get('messenger')
    );
  }

  /**
   * {@inheritdoc}
   */
  protected function getEditableConfigNames(): array {
    return ['selectify.settings'];
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId(): string {
    return 'selectify_settings_form';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state): array {
    $config = $this->config('selectify.settings');

    // Attach a library for styling the radio buttons.
    $form['#attached']['library'][] = 'selectify/selectify-settings-style';

    // =========================================================================
    // SECTION 1: Page Control Settings
    // =========================================================================
    $form['page_control'] = [
      '#type' => 'details',
      '#title' => $this->t('Page Control Settings'),
      '#description' => $this->t('Control where Selectify is enabled or disabled on your site.'),
      '#open' => TRUE,
      '#weight' => 0,
    ];

    $form['page_control']['disable_on_admin_routes'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Disable Selectify on admin routes'),
      '#description' => $this->t('When enabled, Selectify will be disabled on all administrative pages (paths starting with <code>/admin</code>). This prevents conflicts with admin interfaces.'),
      '#default_value' => $config->get('disable_on_admin_routes'),
    ];

    $form['page_control']['disabled_pages'] = [
      '#type' => 'textarea',
      '#title' => $this->t('Additional pages to disable Selectify'),
      '#description' => $this->t('Enter one URL path per line where Selectify should be completely disabled. You can use wildcards (*) for pattern matching.<br><strong>Examples:</strong><ul><li><code>admin/appearance/settings/gin</code> - exact match</li><li><code>admin/appearance/settings/*</code> - all theme settings</li><li><code>*/node/*/edit</code> - all node edit pages</li><li><code>admin/config/*</code> - all config pages</li></ul>'),
      '#default_value' => $config->get('disabled_pages') ?? "admin/appearance/settings/gin",
      '#rows' => 6,
    ];

    // =========================================================================
    // SECTION 2: Radio Button Styling
    // =========================================================================
    $form['radio_settings'] = [
      '#type' => 'details',
      '#title' => $this->t('Radio Button Styling'),
      '#description' => $this->t('Customize the appearance of radio buttons throughout your site.'),
      '#open' => TRUE,
      '#weight' => 10,
    ];

    $form['radio_settings']['enable_radio'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enable custom styles for radio buttons'),
      '#description' => $this->t('Apply Selectify styling to all radio buttons. Uncheck to use default browser styles.'),
      '#default_value' => $config->get('enable_radio'),
    ];

    $form['radio_settings']['radio_style'] = [
      '#type' => 'radios',
      '#title' => $this->t('Radio button style'),
      '#options' => [
        'toggle' => $this->t('Toggle Switch - Modern sliding switch design'),
        'checkbox' => $this->t('Checkbox with X/Checkmark - Traditional style with visual indicator'),
      ],
      '#default_value' => $config->get('radio_style') ?? 'toggle',
      '#states' => [
        'visible' => [
          ':input[name="enable_radio"]' => ['checked' => TRUE],
        ],
      ],
    ];

    $form['radio_settings']['radio_shape'] = [
      '#type' => 'radios',
      '#title' => $this->t('Radio button shape'),
      '#options' => [
        'circle' => $this->t('Circle - Traditional round shape'),
        'square' => $this->t('Square - Modern rectangular shape'),
      ],
      '#default_value' => $config->get('radio_shape') ?? 'circle',
      '#states' => [
        'visible' => [
          ':input[name="enable_radio"]' => ['checked' => TRUE],
        ],
      ],
    ];

    $form['radio_settings']['radio_size'] = [
      '#type' => 'radios',
      '#title' => $this->t('Radio button size'),
      '#options' => [
        'small' => $this->t('Small - Compact for dense forms'),
        'medium' => $this->t('Medium - Recommended for most use cases'),
        'large' => $this->t('Large - Better for accessibility and touch interfaces'),
      ],
      '#default_value' => $config->get('radio_size') ?? 'medium',
      '#states' => [
        'visible' => [
          ':input[name="enable_radio"]' => ['checked' => TRUE],
        ],
      ],
    ];

    // =========================================================================
    // SECTION 3: Checkbox Styling
    // =========================================================================
    $form['checkbox_settings'] = [
      '#type' => 'details',
      '#title' => $this->t('Checkbox Styling'),
      '#description' => $this->t('Customize the appearance of checkboxes throughout your site.'),
      '#open' => TRUE,
      '#weight' => 20,
    ];

    $form['checkbox_settings']['enable_checkbox'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Enable custom styles for checkboxes'),
      '#description' => $this->t('Apply Selectify styling to all checkboxes. Uncheck to use default browser styles.'),
      '#default_value' => $config->get('enable_checkbox'),
    ];

    $form['checkbox_settings']['checkbox_style'] = [
      '#type' => 'radios',
      '#title' => $this->t('Checkbox style'),
      '#options' => [
        'toggle' => $this->t('Toggle Switch - Modern sliding switch design'),
        'checkbox' => $this->t('Checkbox with Checkmark - Traditional style with visual indicator'),
      ],
      '#default_value' => $config->get('checkbox_style') ?? 'toggle',
      '#states' => [
        'visible' => [
          ':input[name="enable_checkbox"]' => ['checked' => TRUE],
        ],
      ],
    ];

    $form['checkbox_settings']['checkbox_shape'] = [
      '#type' => 'radios',
      '#title' => $this->t('Checkbox shape'),
      '#options' => [
        'circle' => $this->t('Circle - Modern rounded style'),
        'square' => $this->t('Square - Traditional checkbox shape'),
      ],
      '#default_value' => $config->get('checkbox_shape') ?? 'circle',
      '#states' => [
        'visible' => [
          ':input[name="enable_checkbox"]' => ['checked' => TRUE],
        ],
      ],
    ];

    $form['checkbox_settings']['checkbox_size'] = [
      '#type' => 'radios',
      '#title' => $this->t('Checkbox size'),
      '#options' => [
        'small' => $this->t('Small - Compact for dense forms'),
        'medium' => $this->t('Medium - Recommended for most use cases'),
        'large' => $this->t('Large - Better for accessibility and touch interfaces'),
      ],
      '#default_value' => $config->get('checkbox_size') ?? 'medium',
      '#states' => [
        'visible' => [
          ':input[name="enable_checkbox"]' => ['checked' => TRUE],
        ],
      ],
    ];

    // =========================================================================
    // SECTION 4: Color Theme
    // =========================================================================
    $form['color_theme'] = [
      '#type' => 'details',
      '#title' => $this->t('Color Theme'),
      '#description' => $this->t('Choose accent colors for radio buttons and checkboxes when selected.'),
      '#open' => FALSE,
      '#weight' => 30,
    ];

    $form['color_theme']['accent_color_mode'] = [
      '#type' => 'radios',
      '#title' => $this->t('Color mode'),
      '#description' => $this->t('Choose between light and dark variants of the selected accent color.'),
      '#options' => [
        'none' => $this->t('None - Use default browser colors'),
        'light' => $this->t('Light'),
        'dark' => $this->t('Dark'),
      ],
      '#default_value' => $config->get('accent_color_mode') ?? 'light',
    ];

    $form['color_theme']['accent_color'] = [
      '#type' => 'radios',
      '#title' => $this->t('Accent color'),
      '#description' => $this->t('Choose the color that appears when a radio button or checkbox is selected.'),
      '#default_value' => $config->get('accent_color') ?? 'blue',
      '#options' => [
        'blue' => $this->t('Blue'),
        'coral' => $this->t('Coral'),
        'gold' => $this->t('Gold'),
        'indigo' => $this->t('Indigo'),
        'neutral' => $this->t('Neutral'),
        'slate' => $this->t('Slate'),
        'teal' => $this->t('Teal'),
      ],
      '#states' => [
        'disabled' => [
          ':input[name="accent_color_mode"]' => ['value' => 'none'],
        ],
      ],
      '#after_build' => [
        [get_called_class(), 'addDataAccent'],
      ],
    ];

    // =========================================================================
    // SECTION 5: Views Select Filters
    // =========================================================================
    $form['views_filters'] = [
      '#type' => 'details',
      '#title' => $this->t('Views Select Filters'),
      '#description' => $this->t('Configure custom widgets for Views exposed filters. Choose between site-wide or per-view configuration.'),
      '#open' => FALSE,
      '#weight' => 40,
    ];

    $form['views_filters']['disable_views_widgets'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Disable Selectify for all Views filters'),
      '#description' => $this->t('When enabled, all Views exposed select filters will use their default widgets.'),
      '#default_value' => $config->get('disable_views_widgets'),
    ];

    $form['views_filters']['apply_site_wide'] = [
      '#type' => 'checkbox',
      '#title' => $this->t('Apply Selectify to all Views exposed filters site-wide'),
      '#description' => $this->t('When enabled, all Views exposed select filters will use the widget selected below. This overrides individual view configurations.'),
      '#default_value' => $config->get('apply_site_wide'),
      '#states' => [
        'visible' => [
          ':input[name="disable_views_widgets"]' => ['checked' => FALSE],
        ],
      ],
    ];

    $form['views_filters']['global_selectify_widget'] = [
      '#type' => 'select',
      '#title' => $this->t('Site-wide widget style'),
      '#description' => $this->t('This widget will be applied to all Views exposed select filters across your site.'),
      '#options' => [
        'none' => $this->t('None - Use default widgets'),
        'selectify_dropdown' => $this->t('Dropdown - Enhanced dropdown with better styling'),
        'selectify_tags' => $this->t('Tags - Enhanced dropdown displaying selections as removable tags'),
        'selectify_searchable' => $this->t('Searchable - Enhanced dropdown with search/filter capability'),
        'selectify_checkbox' => $this->t('Checkbox - Enhanced dropdown with checkbox-style selections'),
        'selectify_dual' => $this->t('Dual List - Side-by-side selection (available/selected lists)'),
      ],
      '#default_value' => $config->get('global_selectify_widget') ?? 'none',
      '#states' => [
        'visible' => [
          ':input[name="disable_views_widgets"]' => ['checked' => FALSE],
          ':input[name="apply_site_wide"]' => ['checked' => TRUE],
        ],
      ],
    ];

    // Per-view widget configuration.
    $form['views_filters']['per_view_configuration'] = [
      '#type' => 'container',
      '#states' => [
        'visible' => [
          ':input[name="disable_views_widgets"]' => ['checked' => FALSE],
          ':input[name="apply_site_wide"]' => ['checked' => FALSE],
        ],
      ],
    ];

    $form['views_filters']['per_view_configuration']['description'] = [
      '#type' => 'markup',
      '#markup' => '<div class="messages messages--info">' . $this->t('<strong>Per-View Configuration:</strong> Select individual widgets for each View display below. Only Views with exposed select filters are shown.') . '</div>',
    ];

    $all_filters = $this->getExposedFilters();
    if (!empty($all_filters)) {
      $stored_filters = $config->get('widget_for_filters', []);
      $grouped_displays = [];

      // Group displays by view.
      foreach ($all_filters as $display_data) {
        $view_machine_name = $display_data['view_machine_name'];
        $grouped_displays[$view_machine_name][] = $display_data;
      }

      $form['views_filters']['per_view_configuration']['selectify_widgets'] = [
        '#tree' => TRUE,
      ];

      foreach ($grouped_displays as $view_machine_name => $displays) {
        $view_human_name = $displays[0]['view_human_name'];

        $form['views_filters']['per_view_configuration']['selectify_widgets'][$view_machine_name] = [
          '#type' => 'details',
          '#title' => $view_human_name,
          '#open' => FALSE,
        ];

        $form['views_filters']['per_view_configuration']['selectify_widgets'][$view_machine_name]['filters_table'] = [
          '#type' => 'table',
          '#header' => [
            $this->t('Display Name'),
            $this->t('Display Type'),
            $this->t('Display ID'),
            $this->t('Exposed Form ID'),
            $this->t('Selectify Widget'),
          ],
          '#tree' => TRUE,
        ];

        foreach ($displays as $display_data) {
          $unique_key = $display_data['view_machine_name'] . ':' . $display_data['display_id'];

          // Check if this row has a selected widget (not 'none').
          $selected_widget = $stored_filters[$unique_key]['widget'] ?? 'none';
          $row_class = ($selected_widget !== 'none') ? 'selected-widget-row' : '';

          $form['views_filters']['per_view_configuration']['selectify_widgets'][$view_machine_name]['filters_table'][$unique_key] = [
          // Add class dynamically.
            '#attributes' => ['class' => [$row_class]],
            'display_title' => [
              '#markup' => '<strong>' . $display_data['display_title'] . '</strong>',
            ],
            'display_type' => [
              '#markup' => ucfirst(str_replace('_', ' ', $display_data['display_type'])),
            ],
            'display_id' => [
              '#markup' => '<code>' . $display_data['display_id'] . '</code>',
            ],
            'exposed_form_id' => [
              '#markup' => "<code>{$display_data['exposed_form_id']}</code>",
            ],
            'widget' => [
              '#type' => 'select',
              '#title' => $this->t('Widget for %label', ['%label' => $display_data['display_title']]),
              '#title_display' => 'invisible',
              '#options' => [
                'none' => $this->t('None'),
                'selectify_dropdown' => $this->t('Dropdown - Enhanced dropdown with better styling'),
                'selectify_tags' => $this->t('Tags - Enhanced dropdown displaying selections as removable tags'),
                'selectify_searchable' => $this->t('Searchable - Enhanced dropdown with search/filter capability'),
                'selectify_checkbox' => $this->t('Checkbox - Enhanced dropdown with checkbox-style selections'),
                'selectify_dual' => $this->t('Dual List - Side-by-side selection (available/selected lists)'),
              ],
              '#default_value' => $selected_widget,
              '#parents' => ['selectify_widgets',
                $view_machine_name, 'filters_table',
                $unique_key, 'widget',
              ],
            ],
          ];
        }
      }
    }
    else {
      $form['views_filters']['per_view_configuration']['no_views'] = [
        '#type' => 'markup',
        '#markup' => '<div class="messages messages--warning">' . $this->t('No Views with exposed select filters were found. Create a View with exposed filters to configure Selectify widgets.') . '</div>',
      ];
    }

    return parent::buildForm($form, $form_state);
  }

  /**
   * Adds data-accent attributes to each radio button for visual styling.
   *
   * This callback adds data attributes to accent color radio buttons,
   * allowing CSS to display color circles instead of text labels.
   *
   * @param array $element
   *   The form element being processed.
   *
   * @return array
   *   The modified form element with data attributes added.
   */
  public static function addDataAccent(array $element): array {
    foreach ($element['#options'] as $key => $label) {
      $element[$key]['#attributes']['data-accent'] = $label;
    }
    return $element;
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    $config = $this->configFactory()->getEditable('selectify.settings');

    // Preserve existing settings while updating necessary ones.
    $config->set('enable_radio', (bool) $form_state->getValue('enable_radio', FALSE))
      ->set('radio_style', $form_state->getValue('radio_style', 'toggle'))
      ->set('radio_shape', $form_state->getValue('radio_shape', 'circle'))
      ->set('radio_size', $form_state->getValue('radio_size', 'medium'))
      ->set('enable_checkbox', (bool) $form_state->getValue('enable_checkbox', FALSE))
      ->set('checkbox_style', $form_state->getValue('checkbox_style', 'toggle'))
      ->set('checkbox_shape', $form_state->getValue('checkbox_shape', 'circle'))
      ->set('checkbox_size', $form_state->getValue('checkbox_size', 'medium'))
      ->set('disable_on_admin_routes', (bool) $form_state->getValue('disable_on_admin_routes', FALSE))
      ->set('disabled_pages', $form_state->getValue('disabled_pages', ''))
      ->set('accent_color', $form_state->getValue('accent_color', $config->get('accent_color', 'neutral')))
      ->set('accent_color_mode', $form_state->getValue('accent_color_mode', $config->get('accent_color_mode', 'light')));

    // Retrieve values from form.
    $apply_site_wide = (bool) $form_state->getValue('apply_site_wide', FALSE);
    $disable_views_widgets = (bool) $form_state->getValue('disable_views_widgets', FALSE);
    $global_widget = $form_state->getValue('global_selectify_widget', $config->get('global_selectify_widget', 'none'));
    $views_widgets = $form_state->getValue('selectify_widgets', []);

    // If disabling Views Select, clear everything.
    if ($disable_views_widgets) {
      $config->set('disable_views_widgets', TRUE)
        ->clear('apply_site_wide')
        ->clear('global_selectify_widget')
        ->clear('widget_for_filters');

      $this->messenger->addMessage($this->t('Selectify has been disabled for all Views filters. All related settings have been cleared.'), 'warning');
    }
    // If applying site-wide Views Select, store global settings/clear widgets.
    elseif ($apply_site_wide) {
      $config->set('apply_site_wide', TRUE)
        ->set('disable_views_widgets', FALSE)
        ->set('global_selectify_widget', $global_widget)
        ->clear('widget_for_filters');

      $this->messenger->addMessage($this->t('Global Selectify widget applied site-wide to all Views exposed filters.'), 'status');
    }
    // If specific widgets are selected, store them & clear global settings.
    elseif (!empty($views_widgets)) {
      $stored_widgets = $this->processViewsWidgetSettings($form_state, $config);

      $config->set('apply_site_wide', FALSE)
        ->set('disable_views_widgets', FALSE)
        ->set('widget_for_filters', $stored_widgets)
        ->clear('global_selectify_widget');

      $this->messenger->addMessage($this->t('Custom Selectify widgets applied to specific Views filters.'), 'status');
    }

    $config->save();
    parent::submitForm($form, $form_state);
  }

  /**
   * Processes Views widget settings and returns updated widget configuration.
   *
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current form state.
   * @param \Drupal\Core\Config\Config $config
   *   The Selectify configuration object.
   *
   * @return array
   *   An associative array of Views widget settings.
   */
  private function processViewsWidgetSettings(FormStateInterface $form_state, Config $config) {

    $stored_widgets = $config->get('widget_for_filters', []);
    $views_data = $form_state->getValue('selectify_widgets', []);

    if (!empty($views_data) && is_array($views_data)) {
      foreach ($views_data as $view_machine_name => $view_content) {
        if (!isset($view_content['filters_table']) || !is_array($view_content['filters_table'])) {
          continue;
        }

        foreach ($view_content['filters_table'] as $unique_key => $values) {
          if (!empty($values['widget']) && $values['widget'] !== 'none') {
            $exposed_form_id = $values['exposed_form_id'] ?? '';

            // Generate `exposed_form_id` if missing.
            if (empty($exposed_form_id)) {
              [$view_machine_name, $display_id] = explode(':', $unique_key, 2);
              $exposed_form_id = "views-exposed-form-{$view_machine_name}-{$display_id}";
            }

            $stored_widgets[$unique_key] = [
              'widget' => $values['widget'],
              'exposed_form_id' => $exposed_form_id,
            ];
          }
        }
      }
    }

    return $stored_widgets;
  }

  /**
   * Retrieves all Views displays with exposed select filters.
   *
   * @return array
   *   An array of exposed forms grouped by View & Display, only including
   *   displays that have at least one exposed select/dropdown filter.
   */
  protected function getExposedFilters(): array {
    $filters = [];
    $views = Views::getAllViews();

    foreach ($views as $view) {
      $view_machine_name = $view->id();
      $view_human_name = $view->label();
      $displays = $view->get('display');

      // Get default display filters for inheritance checking.
      $default_filters = $displays['default']['display_options']['filters'] ?? [];

      foreach ($displays as $display_id => $display) {
        $display_type = $display['display_plugin'];
        $exposed_form_id = "views-exposed-form-{$view_machine_name}-{$display_id}";
        $has_select_filter = FALSE;

        // Get display title.
        $display_title = $display['display_title'] ?? $this->t('Untitled Display');

        // Determine which filters to use for this display.
        $display_filters = $this->resolveDisplayFilters($display, $default_filters);

        // Check if this display has an exposed SELECT filter.
        if (!empty($display_filters)) {
          foreach ($display_filters as $filter) {
            // Skip if filter data is invalid.
            if (!is_array($filter)) {
              continue;
            }

            // Check if filter is exposed AND is a select/dropdown widget.
            if (!empty($filter['exposed']) &&
                !empty($filter['expose']['identifier'])) {

              // Determine the widget type.
              $widget = $this->getFilterWidget($filter);

              // Include filters that use select-based widgets.
              if (in_array($widget, ['select', 'radios'], TRUE)) {
                $has_select_filter = TRUE;
                break;
              }
            }
          }
        }

        // Only add this display if it has an exposed SELECT filter.
        if ($has_select_filter) {
          $unique_key = "{$view_machine_name}:{$display_id}";

          // Store display information.
          $filters[$unique_key] = [
            'view_machine_name' => $view_machine_name,
            'view_human_name' => $view_human_name,
            'display_id' => $display_id,
            'display_title' => $display_title,
            'display_type' => $display_type,
            'exposed_form_id' => $exposed_form_id,
          ];
        }
      }
    }

    return $filters;
  }

  /**
   * Resolves the actual filters for a display, handling inheritance.
   *
   * @param array $display
   *   The display configuration array.
   * @param array $default_filters
   *   The filters from the default display.
   *
   * @return array
   *   The resolved filters for the display.
   */
  protected function resolveDisplayFilters(array $display, array $default_filters): array {
    // Get display options with safe fallback.
    $display_options = $display['display_options'] ?? [];

    // Check current display filters first.
    $display_filters = $display_options['filters'] ?? [];

    // Check if display has explicitly configured defaults.
    $defaults = $display_options['defaults'] ?? [];

    // Determine if this display uses default filters:
    // 1. If 'defaults' key doesn't exist, display inherits from default.
    // 2. If 'defaults.filters' is TRUE or not set, display inherits.
    // 3. If 'defaults.filters' is FALSE, display uses its own filters.
    if (!isset($defaults['filters'])) {
      // No defaults configuration means inherit everything.
      return empty($display_filters) ? $default_filters : $display_filters;
    }

    if ($defaults['filters'] === TRUE) {
      // Explicitly set to use defaults.
      return $default_filters;
    }

    if ($defaults['filters'] === FALSE) {
      // Display explicitly overrides filters, use only display filters.
      return $display_filters;
    }

    // Fallback: if display has filters, use them; otherwise inherit.
    return empty($display_filters) ? $default_filters : $display_filters;
  }

  /**
   * Determines the widget type for a filter.
   *
   * @param array $filter
   *   The filter configuration array.
   *
   * @return string
   *   The widget type (e.g., 'select', 'radios', 'textfield').
   */
  protected function getFilterWidget(array $filter): string {
    // Check for explicitly set widget in expose configuration.
    if (isset($filter['expose']['widget'])) {
      return $filter['expose']['widget'];
    }

    // Check for widget in expose settings (alternative location).
    if (isset($filter['expose']['settings']['widget'])) {
      return $filter['expose']['settings']['widget'];
    }

    // Check the filter type - some filters default to select.
    $filter_type = $filter['type'] ?? '';

    // Common filter types that default to select widgets.
    $select_filter_types = [
      'select',
      'taxonomy_index_tid',
      'bundle',
      'boolean',
      'list_field',
      'entity_reference',
    ];

    if (in_array($filter_type, $select_filter_types, TRUE)) {
      return 'select';
    }

    // Default to 'select' if no widget is specified (most common case).
    return 'select';
  }

}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc