You are here

select2boxes.module in Select2 Boxes 8

Basic module file.

File

select2boxes.module
View source
<?php

/**
 * @file
 * Basic module file.
 */
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\WidgetInterface;
use Drupal\Core\Form\FormStateInterface;

/**
 * Implements hook_help().
 */
function select2boxes_help($route_name) {
  switch ($route_name) {
    case 'help.page.select2boxes':
      $output = 'Provides Select2 widgets.';
      return $output;
  }
}

/**
 * Implements hook_library_info_build().
 */
function select2boxes_library_info_build() {

  // Prepare required config's data.
  $config = \Drupal::config('select2boxes.settings');
  $version = $config
    ->get('version');
  $url = $config
    ->get('url');
  $options = [
    'minified' => TRUE,
    'external' => TRUE,
  ];
  $libraries['select2'] = [
    'remote' => 'https://github.com/select2/select2',
    // Set a version specified in the config form.
    'version' => $version,
    'license' => [
      'name' => 'MIT',
      'url' => 'https://github.com/select2/select2/blob/master/LICENSE.md',
      'gpl-compatible' => TRUE,
    ],
    // Using CDN url and version
    // attach an appropriate external CSS and JS files.
    'css' => [
      'theme' => [
        "{$url}/{$version}/css/select2.min.css" => $options,
      ],
    ],
    'js' => [
      "{$url}/{$version}/js/select2.full.min.js" => $options,
    ],
  ];
  return $libraries;
}

/**
 * Implements hook_library_info_alter().
 */
function select2boxes_library_info_alter(&$libraries, $extension) {

  // Specify library version for our widget
  // to make it the same as we have for Select2 library.
  if ($extension == 'select2boxes' && isset($libraries['widget'])) {
    $version = \Drupal::config('select2boxes.settings')
      ->get('version');
    if (!empty($version)) {
      $libraries['widget']['version'] = $version;
    }
  }
}

/**
 * Implements hook_field_widget_third_party_settings_form().
 */
function select2boxes_field_widget_third_party_settings_form(WidgetInterface $plugin, FieldDefinitionInterface $field_definition) {

  // Get all third party settings provided by this module.
  $settings = $plugin
    ->getThirdPartySettings('select2boxes');

  // Add the options, specific for the multiple entity reference widgets.
  if ($plugin
    ->getPluginId() == 'select2boxes_autocomplete_multi') {

    // Add preloading option to the widget settings form.
    $element['enable_preload'] = [
      '#type' => 'checkbox',
      '#title' => t('Enable pre-loaded entries'),
      '#default_value' => isset($settings['enable_preload']) && $settings['enable_preload'] == '1',
    ];
    $field_name = $field_definition
      ->getName();
    $element['preload_count'] = [
      '#type' => 'textfield',
      '#title' => t('Maximum number of entries that will be pre-loaded'),
      '#description' => t('If maximum number is not specified then all entries will be preloaded'),
      '#default_value' => isset($settings['preload_count']) ? $settings['preload_count'] : '',
      '#states' => [
        'visible' => [
          ":input[name=\"fields[{$field_name}][settings_edit_form][third_party_settings][select2boxes][enable_preload]\"]" => [
            'checked' => TRUE,
          ],
        ],
      ],
    ];
    return $element;
  }
  elseif ($plugin
    ->getPluginId() == 'select2boxes_autocomplete_list' || $plugin
    ->getPluginId() == 'select2boxes_autocomplete_single') {

    // Ignore fields with auto-creation option enabled.
    if (isset($field_definition
      ->getSetting('handler_settings')['auto_create'])) {
      return [];
    }

    // Add an option to allow users to include the flag icons.
    $types = [
      'language_field',
      'language',
      'country',
    ];
    if (in_array($field_definition
      ->getType(), $types) && \Drupal::moduleHandler()
      ->moduleExists('flags')) {
      $element['enable_flags'] = [
        '#type' => 'checkbox',
        '#title' => t('Include flags icons'),
        '#default_value' => isset($settings['enable_flags']) && $settings['enable_flags'] == '1',
      ];
      return $element;
    }
  }
  elseif (in_array($plugin
    ->getPluginId(), _select2boxes_address_widgets_list())) {
    $element['enable_select2'] = [
      '#type' => 'checkbox',
      '#title' => t('Enable Select2 widget for dropdowns'),
      '#default_value' => isset($settings['enable_select2']) && $settings['enable_select2'] == '1',
    ];
    return $element;
  }
  return [];
}

/**
 * Implements hook_field_widget_settings_summary_alter().
 */
function select2boxes_field_widget_settings_summary_alter(&$summary, $context) {

  // Add content to the summary to allow users to see all custom options status.

  /** @var \Drupal\Core\Field\WidgetInterface $widget */
  $widget = $context['widget'];
  $settings = $widget
    ->getThirdPartySettings('select2boxes');
  if ($widget
    ->getPluginId() == 'select2boxes_autocomplete_multi') {
    if (!empty($settings) && $settings['enable_preload'] == '1') {
      $count = $settings['preload_count'] || $settings['preload_count'] == '0' ? $settings['preload_count'] : 'all';
      $summary[] = t('Number of preloaded entries: @count', [
        '@count' => $count,
      ]);
    }
    else {
      $summary[] = t('Preloading disabled');
    }
  }
  elseif ($widget
    ->getPluginId() == 'select2boxes_autocomplete_list' || $widget
    ->getPluginId() == 'select2boxes_autocomplete_single') {

    /** @var \Drupal\field\Entity\FieldConfig $definition */
    $definition = $context['field_definition'];
    $flag_types = [
      'language_field',
      'language',
      'country',
    ];
    if (in_array($definition
      ->getType(), $flag_types) && \Drupal::moduleHandler()
      ->moduleExists('flags')) {
      if (!empty($settings) && $settings['enable_flags'] == '1') {
        $summary[] = t('Flags icons enabled');
      }
      else {
        $summary[] = t('Flags icons disabled');
      }
    }
  }
  elseif (in_array($widget
    ->getPluginId(), _select2boxes_address_widgets_list())) {
    if (!empty($settings) && $settings['enable_select2'] == '1') {
      $summary[] = t('Select2 enabled');
    }
    else {
      $summary[] = t('Select2 disabled');
    }
  }
}

/**
 * Implements hook_field_widget_form_alter().
 */
function select2boxes_field_widget_form_alter(&$element, FormStateInterface $form_state, $context) {

  /** @var \Drupal\Core\Field\WidgetInterface $plugin */
  $plugin = $context['widget'];

  /** @var \Drupal\Core\Field\FieldItemList $items */
  $items = $context['items'];
  if (in_array($plugin
    ->getPluginId(), _select2boxes_address_widgets_list())) {
    $settings = $plugin
      ->getThirdPartySettings('select2boxes');
    if (!empty($settings['enable_select2'])) {

      // Put all field names with enabled Select2 option to the drupalSettings
      // to allow Drupal's JS behavior handle it.
      $element['#attached']['library'][] = 'select2boxes/widget';
      $element['#attached']['drupalSettings']['addressFieldsSelect2'][$items
        ->getName()] = TRUE;
    }
  }
}

/**
 * Get a list of address fields widgets supported.
 *
 * @return array
 *   List of address fields widgets supported.
 */
function _select2boxes_address_widgets_list() {
  return \Drupal::moduleHandler()
    ->moduleExists('address') ? [
    'address_default',
    'address_country_default',
    'address_zone_default',
  ] : [];
}

/**
 * Implements template_preprocess_select().
 */
function select2boxes_preprocess_select(&$vars) {
  $config = \Drupal::config('select2boxes.settings');
  $global = (bool) $config
    ->get('select2_global');
  if ($global) {
    $is_disabled_for_admin = (bool) $config
      ->get('disable_for_admin_pages');
    if ($is_disabled_for_admin) {

      /** @var \Drupal\Core\Routing\AdminContext $admin_context */
      $admin_context = \Drupal::service('router.admin_context');
      if ($admin_context
        ->isAdminRoute()) {
        return;
      }
    }
    $attrs =& $vars['attributes'];
    $attrs['data-jquery-once-autocomplete'] = 'true';
    $attrs['data-select2-autocomplete-list-widget'] = 'true';
    $attrs['class'][] = 'select2-widget';
    $vars['#attached']['library'][] = 'select2boxes/widget';

    // Handle limited search option for globally enabled select2 widgets.
    if ($config
      ->get('limited_search') == '1') {
      $attrs['data-minimum-search-length'] = $config
        ->get('minimum_search_length') ?: 0;
    }
  }
}

/**
 * Implements hook_page_attachments_alter().
 */
function select2boxes_page_attachments_alter(array &$attachments) {

  // Set our library to already loaded list if the big_pipe module is enabled
  // in order to prevent library being loaded via BigPipe technology.
  if (\Drupal::moduleHandler()
    ->moduleExists('big_pipe')) {
    $attachments['#attached']['library'][] = 'select2boxes/widget';
  }
}