geolocation-8.x-3.x-dev/modules/geolocation_address/geolocation_address.module

modules/geolocation_address/geolocation_address.module
<?php

/**
 * @file
 * Provide address integration where due.
 */

use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\WidgetInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Url;
use Drupal\geolocation\Plugin\Field\FieldWidget\GeolocationMapWidget;
use Drupal\geolocation_address\Plugin\migrate\field\Location;

/**
 * Implements hook_geolocation_field_map_widget_alter().
 */
function geolocation_address_geolocation_field_map_widget_alter(array &$element, array $context): void {
  /** @var \Drupal\geolocation\Plugin\Field\FieldWidget\GeolocationMapWidget $widget */
  $widget = $context['widget'];

  /** @var \Drupal\Core\Field\FieldDefinitionInterface $field_definition */
  $field_definition = $context['field_definition'];

  $settings = geolocation_address_get_widget_settings($widget);

  if (empty($settings['enable'])) {
    return;
  }

  $address_label = t('Address');
  /** @var \Drupal\Core\Field\FieldDefinitionInterface[] $all_field_definitions */
  $all_field_definitions = Drupal::service('entity_field.manager')->getFieldDefinitions(
    $field_definition->getTargetEntityTypeId(),
    $field_definition->getTargetBundle()
  );

  foreach ($all_field_definitions as $single_field_definition) {
    if ($single_field_definition->getName() == $settings['address_field']) {
      $address_label = $single_field_definition->getLabel();
    }
  }

  $geocoder_token = \Drupal::service('csrf_token')->get(Url::fromRoute('geolocation_address.geocoder.geocode')->getInternalPath());
  $geocoder_url = Url::fromRoute(
    route_name: 'geolocation_address.geocoder.geocode',
    options: ['query' => ['token' => $geocoder_token]]
  )->toString();

  $geocoder_reverse_token = \Drupal::service('csrf_token')->get(Url::fromRoute('geolocation_address.geocoder.reverse')->getInternalPath());
  $geocoder_reverse_url = Url::fromRoute(
    route_name: 'geolocation_address.geocoder.reverse',
    options: ['query' => ['token' => $geocoder_reverse_token]]
  )->toString();

  $element['#attached'] = BubbleableMetadata::mergeAttachments(
    empty($element['#attached']) ? [] : $element['#attached'],
    [
      'drupalSettings' => [
        'geolocation' => [
          'widgetSettings' => [
            $element['#attributes']['id'] => [
              'widgetSubscribers' => [
                'address_widget' => [
                  'import_path' => base_path()
                  . Drupal::service('module_handler')->getModule('geolocation_address')->getPath()
                  . '/js/WidgetSubscriber/GeolocationAddressWidget.js',
                  'settings' => [
                    'field_name' => $settings['address_field'],
                    'geocoder' => $settings['geocoder'],
                    'settings' => $settings['settings'],
                    'sync_mode' => $settings['sync_mode'],
                    'direction' => $settings['direction'],
                    'ignore' => $settings['ignore'],
                    'geocoder_url' => $geocoder_url,
                    'geocoder_reverse_url' => $geocoder_reverse_url,
                  ],
                ],
              ],
            ],
          ],
        ],
      ],
    ],
  );

  $element['#attributes'] = BubbleableMetadata::mergeAttachments(
    empty($element['#attributes']) ? [] : $element['#attributes'],
    ['data-address-integration' => $element['widget']['#field_name']]
  );

  if ($settings['sync_mode'] == 'manual') {
    if (empty($element['map'])) {
      return;
    }

    $element['map']['#controls']['geolocation_address'] = [
      '#type' => 'container',
      '#attributes' => [
        'class' => [
          'geolocation-map-control',
          'geolocation-address',
        ],
      ],
    ];
    if (!empty($element['#address_settings']['button_position'])) {
      $element['map']['#controls']['geolocation_address']['#attributes']['data-control-position'] = $element['#address_settings']['button_position'];
    }

    $element['map']['#controls']['geolocation_address']['address_pull'] = [
      '#type' => 'html_tag',
      '#tag' => 'button',
      '#attributes' => [
        'class' => [
          'address-button',
          'address-button-pull',
        ],
        'title' => t('Pull all address from %address onto map', ['%address' => $address_label]),
      ],
      '#value' => t('Pull from %address', ['%address' => $address_label]),
    ];

    if ($settings['direction'] == 'duplex') {
      $element['map']['#controls']['geolocation_address']['address_push'] = [
        '#type' => 'html_tag',
        '#tag' => 'button',
        '#attributes' => [
          'class' => [
            'address-button',
            'address-button-push',
          ],
          'title' => t('Push current location data to %address', ['%address' => $address_label]),
        ],
        '#value' => t('Push to %address', ['%address' => $address_label]),
      ];
    }
  }
}

/**
 * Implements hook_field_widget_third_party_settings_form().
 */
function geolocation_address_field_widget_third_party_settings_form(WidgetInterface $widget, FieldDefinitionInterface $field_definition, string $form_mode, array $form, FormStateInterface $form_state): array {
  if (!($widget instanceof GeolocationMapWidget)) {
    return [];
  }

  /** @var \Drupal\geolocation\Plugin\Field\FieldWidget\GeolocationMapWidget $widget */

  $field_storage_definition = $field_definition->getFieldStorageDefinition();

  $form_parent_name = 'fields[' . $field_definition->getName() . '][settings_edit_form][third_party_settings][geolocation_address]';

  $settings = geolocation_address_get_widget_settings($widget);
  if (!empty($form_state->getTriggeringElement()['#name']) && $form_state->getTriggeringElement()['#name'] == $form_parent_name . '[geocoder]') {
    $settings['geocoder'] = $form_state->getTriggeringElement()['#value'];
  }

  /** @var \Drupal\Core\Field\FieldDefinitionInterface[] $all_field_definitions */
  $all_field_definitions = Drupal::service('entity_field.manager')->getFieldDefinitions($field_definition->getTargetEntityTypeId(), $field_definition->getTargetBundle());

  $address_fields = [];
  foreach ($all_field_definitions as $single_field_definition) {
    if (
      $single_field_definition->getType() == 'address'
      && ($single_field_definition->getFieldStorageDefinition()->getCardinality() == $field_storage_definition->getCardinality())
    ) {
      $address_fields[$single_field_definition->getName()] = $single_field_definition->getLabel();
    }
  }

  if (empty($address_fields)) {
    return [];
  }

  /** @var \Drupal\geolocation\GeocoderManager $geocoder_manager */
  $geocoder_manager = Drupal::service('plugin.manager.geolocation.geocoder');

  $geocoder_options = [];
  foreach ($geocoder_manager->getDefinitions() as $geocoder_id => $geocoder_definition) {
    if (empty($geocoder_definition['locationCapable'])) {
      continue;
    }
    if (
      $settings['direction'] == 'duplex'
      && empty($geocoder_definition['reverseCapable'])
    ) {
      continue;
    }
    $geocoder_options[$geocoder_id] = $geocoder_definition['name'];
  }

  if (empty($geocoder_options)) {
    return [];
  }

  $element = [
    '#type' => 'details',
    '#title' => t('Address integration'),
    '#open' => TRUE,
  ];

  $element['enable'] = [
    '#type' => 'checkbox',
    '#title' => t('Enable address integration'),
    '#default_value' => $settings['enable'],
  ];

  $element['address_field'] = [
    '#type' => 'select',
    '#title' => t('Select Address Field'),
    '#options' => $address_fields,
    '#default_value' => $settings['address_field'],
    '#states' => [
      'visible' => [
        ':input[name="' . $form_parent_name . '[enable]"]' => ['checked' => TRUE],
      ],
    ],
  ];

  $element['sync_mode'] = [
    '#type' => 'radios',
    '#title' => t('Synchronization'),
    '#default_value' => $settings['sync_mode'],
    '#options' => [
      'auto' => t('Automatically'),
      'manual' => t('Manually by push & pull buttons'),
    ],
    '#states' => [
      'visible' => [
        ':input[name="' . $form_parent_name . '[enable]"]' => ['checked' => TRUE],
      ],
    ],
  ];

  $map_provider = $widget->getMapProvider();

  $control_positions = $map_provider ? $map_provider::getControlPositions() : [];
  if ($control_positions) {
    $element['button_position'] = [
      '#type' => 'select',
      '#title' => t('Button position'),
      '#options' => $control_positions,
      '#default_value' => $settings['button_position'],
      '#states' => [
        'visible' => [
          ':input[name="' . $form_parent_name . '[enable]"]' => ['checked' => TRUE],
          ':input[name="' . $form_parent_name . '[sync_mode]"]' => ['value' => 'manual'],
        ],
      ],
    ];
  }

  $element['direction'] = [
    '#type' => 'radios',
    '#title' => t('Direction'),
    '#default_value' => $settings['direction'],
    '#options' => [
      'duplex' => t('Full Duplex | Address <> Geolocation'),
      'one_way' => t('One Way | Address > Geolocation'),
    ],
    '#states' => [
      'visible' => [
        ':input[name="' . $form_parent_name . '[enable]"]' => ['checked' => TRUE],
      ],
    ],
  ];

  $element['ignore'] = [
    '#type' => 'checkboxes',
    '#title' => t('Ignore Address Elements'),
    '#default_value' => array_keys(array_filter($settings['ignore'])),
    '#options' => [
      'organization' => 'organization',
      'address-line1' => 'address-line1',
      'address-line2' => 'address-line2',
      'locality' => 'locality',
      'administrative-area' => 'administrative-area',
      'postal-code' => 'postal-code',
    ],
    '#states' => [
      'visible' => [
        ':input[name="' . $form_parent_name . '[enable]"]' => ['checked' => TRUE],
      ],
    ],
  ];

  $element['geocoder'] = $geocoder_manager->geocoderOptionsSelect($geocoder_options);
  $element['geocoder'] = array_merge($element['geocoder'], [
    '#default_value' => $settings['geocoder'],
    '#states' => [
      'visible' => [
        ':input[name="' . $form_parent_name . '[enable]"]' => [
          'checked' => TRUE,
        ],
      ],
    ],
  ]);

  $geocoder_plugin = $geocoder_manager->getGeocoder(
    $settings['geocoder'] ?? current(array_keys($geocoder_options)),
    $settings['settings'] ?? []
  );

  if (empty($geocoder_plugin)) {
    $element['geocoder_settings'] = [
      '#type' => 'html_tag',
      '#tag' => 'span',
      '#value' => t("No settings available."),
      '#states' => [
        'visible' => [
          ':input[name="' . $form_parent_name . '[enable]"]' => ['checked' => TRUE],
        ],
      ],
    ];
  }
  else {
    $element['geocoder_settings'] = $geocoder_plugin->getOptionsForm();
    $element['geocoder_settings']['#states'] = [
      'visible' => [
        ':input[name="' . $form_parent_name . '[enable]"]' => ['checked' => TRUE],
      ],
    ];
  }

  return $element;
}

/**
 * Implements hook_field_widget_settings_summary_alter().
 */
function geolocation_address_field_widget_settings_summary_alter(array &$summary, array $context): void {
  $widget = $context['widget'];

  if (!($widget instanceof GeolocationMapWidget)) {
    return;
  }

  $settings = geolocation_address_get_widget_settings($widget);
  if (!empty($settings['enable'])) {
    $summary[] = t('Syncing with %field address field', ['%field' => $settings['address_field']]);
  }
}

/**
 * Returns geolocation_address third party settings of a widget.
 *
 * @param \Drupal\Core\Field\WidgetInterface $widget
 *   The widget.
 *
 * @return array
 *   The widget settings including defaults.
 */
function geolocation_address_get_widget_settings(WidgetInterface $widget): array {
  $settings = $widget->getThirdPartySettings('geolocation_address');

  // Backwards compatibility if the third party settings have the
  // geocoder_settings key but not settings.
  if (isset($settings['geocoder_settings']) && !isset($settings['settings'])) {
    $settings['settings'] = $settings['geocoder_settings'];
    unset($settings['geocoder_settings']);
  }

  return $settings + [
    'enable' => FALSE,
    'address_field' => NULL,
    'geocoder' => NULL,
    'settings' => [],
    'sync_mode' => 'auto',
    'direction' => 'duplex',
    'button_position' => NULL,
    'ignore' => [],
  ];
}

/**
 * Implements hook_migrate_field_info_alter().
 */
function geolocation_address_migrate_field_info_alter(array &$definitions): void {
  // When geolocation and also address modules are present, we can migrate both
  // the geological locations and also the addresses into their own field.
  if (!empty($definitions['location'])) {
    $definitions['location']['class'] = Location::class;
    $definitions['location']['provider'] = 'geolocation_address';
  }
}

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

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