You are here

public static function GeofieldMap::latLonProcess in Geofield Map 8.2

Same name and namespace in other branches
  1. 8 src/Element/GeofieldMap.php \Drupal\geofield_map\Element\GeofieldMap::latLonProcess()

Generates the Geofield Map form element.

Parameters

array $element: An associative array containing the properties and children of the element. Note that $element must be taken by reference here, so processed child elements are taken over into $form_state.

\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.

array $complete_form: The complete form structure.

Return value

array The processed element.

File

src/Element/GeofieldMap.php, line 32

Class

GeofieldMap
Provides a Geofield Map form element.

Namespace

Drupal\geofield_map\Element

Code

public static function latLonProcess(array &$element, FormStateInterface $form_state, array &$complete_form) {

  /* @var \Drupal\Core\Config\ConfigFactoryInterface $config */
  $config = \Drupal::configFactory();
  $geofield_map_settings = $config
    ->get('geofield_map.settings');

  /** @var \Drupal\geofield_map\Services\GoogleMapsService $google_maps_service */
  $google_maps_service = \Drupal::service('geofield_map.google_maps');

  /** @var \Drupal\Core\Session\AccountProxyInterface $currentUser */
  $currentUser = \Drupal::currentUser();

  // Initialize the basic geofield_map_element.
  static::elementProcess($element, $form_state, $complete_form);

  // Define the $mapid variable.
  $mapid = $element['#mapid'] = 'map-' . $element['#id'];

  // Map Element.
  $element['map'] = [
    '#type' => 'fieldset',
    '#weight' => 0,
  ];

  // Geocode address textfield and functionality.
  $gmap_geocoder_enabled = \Drupal::moduleHandler()
    ->moduleExists('geocoder') && $element['#gmap_geocoder'];
  $message_recipient = t("(Note: This message is only shown to the Geofield Map module administrator ('Configure Geofield Map' permission).");
  if (strlen($element['#gmap_api_key']) > 0 || $gmap_geocoder_enabled) {
    $element['map']['geocode'] = [
      '#title' => t("Geocode address"),
      '#type' => 'textfield',
      '#description' => t("Use this to geocode your search location."),
      '#size' => 60,
      '#maxlength' => 128,
      '#attributes' => [
        'id' => 'search-' . $element['#id'],
        'class' => [
          'form-text',
          'form-autocomplete',
          'geofield-map-search',
        ],
      ],
    ];
    if ($currentUser
      ->hasPermission('configure geofield_map')) {
      $element['map']['geocode']['#description'] .= '<div class="geofield-map-message">' . t('Search Address Functionalities based on:') . ' ';
      if ($element['#gmap_geocoder']) {
        $element['map']['geocode']['#description'] .= t('Geocoder Module Providers.');
      }
      else {
        $element['map']['geocode']['#description'] .= t('Geofield Map GMaps API Key Geocoder.');
        $element['map']['geocode']['#description'] .= '<br>' . t('@google_places_autocomplete_message', [
          '@google_places_autocomplete_message' => !$element['#gmap_places'] ? 'Google Places Autocomplete Service disabled. Might be enabled in the Geofield Widget configuration.' : 'Google Places Autocomplete Service enabled.',
        ]);
      }
      $element['map']['geocode']['#description'] .= '<br>' . $message_recipient . '</div>';
    }
  }
  elseif ($currentUser
    ->hasPermission('configure geofield_map')) {
    $geocoder_module_link = !\Drupal::moduleHandler()
      ->moduleExists('geocoder') ? \Drupal::service('link_generator')
      ->generate('Geocoder Module', Url::fromUri('https://www.drupal.org/project/geocoder', [
      'attributes' => [
        'target' => 'blank',
      ],
    ])) : 'Geocoder Module';
    $element['map']['geocode_missing'] = [
      '#type' => 'html_tag',
      '#tag' => 'div',
      '#value' => t("Gmap Api Key missing (@settings_page_link) and @geocoder_module_link integration not enabled in this Geofield Widget configuration.<br>The Geocode & ReverseGeocode functionalities are not available.", [
        '@settings_page_link' => \Drupal::linkGenerator()
          ->generate(t('in the Geofield Map Configuration Page'), Url::fromRoute('geofield_map.settings', [], [
          'query' => [
            'destination' => Url::fromRoute('<current>')
              ->toString(),
          ],
        ])),
        '@geocoder_module_link' => $geocoder_module_link,
      ]),
      '#attributes' => [
        'class' => [
          'geofield-map-message',
        ],
      ],
    ];
    $element['map']['geocode_missing']['#value'] .= '<br>' . $message_recipient;
  }
  $element['map']['geofield_map'] = [
    '#theme' => 'geofield_map_widget',
    '#mapid' => $mapid,
    '#width' => isset($element['#map_dimensions']['width']) ? $element['#map_dimensions']['width'] : '100%',
    '#height' => isset($element['#map_dimensions']['height']) ? $element['#map_dimensions']['height'] : '450px',
  ];
  $element['map']['actions'] = [
    '#type' => 'actions',
  ];
  if (!empty($element['#click_to_find_marker']) && $element['#click_to_find_marker'] == TRUE) {
    $element['map']['actions']['click_to_find_marker'] = [
      '#type' => 'button',
      '#value' => t('Find marker'),
      '#name' => 'geofield-map-center',
      '#attributes' => [
        'id' => $element['#id'] . '-click-to-find-marker',
      ],
    ];
    $element['#attributes']['class'] = [
      'geofield-map-center',
    ];
  }
  if (!empty($element['#click_to_place_marker']) && $element['#click_to_place_marker'] == TRUE) {
    $element['map']['actions']['click_to_place_marker'] = [
      '#type' => 'button',
      '#value' => t('Place marker here'),
      '#name' => 'geofield-map-marker',
      '#attributes' => [
        'id' => $element['#id'] . '-click-to-place-marker',
      ],
    ];
    $element['#attributes']['class'] = [
      'geofield-map-marker',
    ];
  }

  // Add the HTML5 User Geolocation button functionality.
  if (!empty($element['#geolocation']) && $element['#geolocation'] == TRUE) {
    $element['#attached']['library'][] = 'geofield_map/geolocation';
    $element['map']['actions']['geolocation'] = [
      '#type' => 'button',
      '#value' => t('Find my location'),
      '#name' => 'geofield-html5-geocode-button',
      '#attributes' => [
        'mapid' => $mapid,
      ],
    ];
    $element['#attributes']['class'] = [
      'auto-geocode',
    ];
  }

  // Define Lat and Lon sub-elements.
  $element['lat']['#weight'] = 10;
  $element['lon']['#weight'] = 20;
  $element['lat']['#attributes']['id'] = 'lat-' . $element['#id'];
  $element['lon']['#attributes']['id'] = 'lon-' . $element['#id'];
  if ($element['#hide_coordinates']) {
    $element['lat']['#attributes']['class'][] = 'visually-hidden';
    $element['lat']['#title_display'] = 'invisible';
    $element['lon']['#attributes']['class'][] = 'visually-hidden';
    $element['lon']['#title_display'] = 'invisible';
  }

  // Geoaddress Field Functionality and Settings.
  $address_field_exists = FALSE;
  if (!empty($element['#geoaddress_field']['field'])) {
    $address_field_name = $element['#geoaddress_field']['field'];
    $parents = array_slice($element['#array_parents'], 0, -4);
    $parents[] = $address_field_name;
    $address_field = NestedArray::getValue($complete_form, $parents, $address_field_exists);
    if ($address_field_exists && ($address_field['widget']['#cardinality'] == '-1' || $address_field['widget']['#cardinality'] > $element['#delta'])) {
      if ($element['#delta'] > 0 && !isset($address_field['widget'][$element['#delta']])) {
        $address_field['widget'][$element['#delta']] = $address_field['widget'][$element['#delta'] - 1];
        $address_field['widget'][$element['#delta']]['#delta'] = $element['#delta'];
        $address_field['widget'][$element['#delta']]['_weight']['#default_value'] = $element['#delta'];
        $address_field['widget'][$element['#delta']]['value']['#default_value'] = NULL;
      }
      $address_field['widget'][$element['#delta']]['value']['#description'] = (string) t('This value will be synchronized with the Geofield Map Reverse-Geocoded value.');
      if ($element['#geoaddress_field']['hidden']) {
        $address_field['#attributes']['class'][] = 'geofield_map_geoaddress_field_hidden';
      }
      if ($element['#geoaddress_field']['disabled']) {
        $address_field['widget'][$element['#delta']]['value']['#attributes']['readonly'] = 'readonly';
        $address_field['widget'][$element['#delta']]['value']['#description'] = (string) t('This field is readonly. It will be synchronized with the Geofield Map Reverse-Geocoded value.');
      }

      // Re-Generate the geoaddress_field #id.
      $address_field['widget'][$element['#delta']]['value']['#id'] = $element['#geoaddress_field']['field'] . '-' . $element['#delta'];
      NestedArray::setValue($complete_form, $parents, $address_field);
    }
  }

  // Attach Geofield Map Libraries.
  $element['#attached']['library'][] = 'geofield_map/geofield_map_general';
  $element['#attached']['library'][] = 'geofield_map/geofield_map_widget';

  // Conditionally use the Leaflet library from the D8 Module, if enabled.
  if ($element['#map_library'] == 'leaflet') {
    $element['#attached']['library'][] = \Drupal::moduleHandler()
      ->moduleExists('leaflet') ? 'leaflet/leaflet' : 'geofield_map/leaflet';
  }

  // The Entity Form.

  /* @var \Drupal\Core\Entity\ContentEntityFormInterface $entity_form */
  $entity_form = $form_state
    ->getBuildInfo()['callback_object'];
  $entity_operation = method_exists($entity_form, 'getOperation') ? $entity_form
    ->getOperation() : 'any';
  $map_settings = [
    'entity_operation' => $entity_operation,
    'widget' => TRUE,
    'id' => $element['#id'],
    'mapid' => $mapid,
    'name' => $element['#name'],
    'lat' => floatval($element['lat']['#default_value']),
    'lng' => floatval($element['lon']['#default_value']),
    'zoom_start' => intval($element['#zoom']['start']),
    'zoom_focus' => intval($element['#zoom']['focus']),
    'zoom_min' => intval($element['#zoom']['min']),
    'zoom_max' => intval($element['#zoom']['max']),
    'latid' => $element['lat']['#attributes']['id'],
    'lngid' => $element['lon']['#attributes']['id'],
    'searchid' => isset($element['map']['geocode']) ? $element['map']['geocode']['#attributes']['id'] : NULL,
    'geoaddress_field_id' => $address_field_exists && isset($address_field['widget'][$element['#delta']]['value']['#id']) ? $address_field['widget'][$element['#delta']]['value']['#id'] : NULL,
    'gmap_places' => $element['#gmap_places'],
    'gmap_places_options' => $element['#gmap_places_options'],
    'gmap_geocoder' => 0,
    'gmap_geocoder_settings' => [],
    'map_library' => $element['#map_library'],
    'map_type' => $element['#map_type'],
    'map_type_selector' => $element['#map_type_selector'] ? TRUE : FALSE,
    'map_types_google' => $element['#map_types_google'],
    'map_types_leaflet' => $element['#map_types_leaflet'],
    'click_to_find_marker_id' => $element['#click_to_find_marker'] ? $element['map']['actions']['click_to_find_marker']['#attributes']['id'] : NULL,
    'click_to_find_marker' => $element['#click_to_find_marker'] ? TRUE : FALSE,
    'click_to_place_marker_id' => $element['#click_to_place_marker'] ? $element['map']['actions']['click_to_place_marker']['#attributes']['id'] : NULL,
    'click_to_place_marker' => $element['#click_to_place_marker'] ? TRUE : FALSE,
    // Geofield Map Google Maps and Geocoder Settings.
    'gmap_api_localization' => $google_maps_service
      ->getGmapApiLocalization($geofield_map_settings
      ->get('gmap_api_localization')),
    'gmap_api_key' => $element['#gmap_api_key'] && strlen($element['#gmap_api_key']) > 0 ? $element['#gmap_api_key'] : NULL,
    'geocoder' => !empty($geofield_map_settings
      ->get('geocoder')) ? $geofield_map_settings
      ->get('geocoder') : [],
  ];

  // Add the Geofield Map Geocoder settings and library if Geocoder Search is
  // Enabled and Accessible.
  if (\Drupal::service('module_handler')
    ->moduleExists('geocoder') && class_exists('\\Drupal\\geocoder\\Controller\\GeocoderApiEnpoints') && $element['#gmap_geocoder'] && \Drupal::service('current_user')
    ->hasPermission('access geocoder api endpoints')) {
    $map_settings['gmap_geocoder'] = $element['#gmap_geocoder'];
    $map_settings['gmap_geocoder_settings'] = $element['#gmap_geocoder_settings'];
    $element['#attached']['library'][] = 'geofield_map/geocoder';
  }

  // Allow other modules to add/alter the geofield map element settings.
  \Drupal::moduleHandler()
    ->alter('geofield_map_latlon_element', $map_settings, $complete_form, $form_state
    ->getValues());

  // Geofield Map Element specific mapid settings.
  $element['#attached']['drupalSettings']['geofield_map'][$mapid] = $map_settings;
  return $element;
}