You are here

OpenlayersGeolocationWidget.php in Openlayers 8.4

File

modules/openlayers_geolocation/src/Plugin/Field/FieldWidget/OpenlayersGeolocationWidget.php
View source
<?php

namespace Drupal\openlayers\Plugin\Field\FieldWidget;

use Drupal\Core\Field\WidgetBase;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\geolocation\Plugin\Field\FieldType\GeolocationItem;
use Drupal\openlayers\OpenlayersService;
use Drupal\openlayers\MapSettings;

/**
 * Plugin implementation of an Openlayers widget.
 *
 * @FieldWidget(
 *   id = "openlayers_geolocation_widget",
 *   label = @Translation("Openlayers Map"),
 *   description = @Translation("Provides an Openlayers widget."),
 *   field_types = {
 *     "geolocation",
 *   },
 * )
 */
class OpenlayersGeolocationWidget extends OpenlayersWidgetBase {

  /**
   * {@inheritdoc}
   */
  public static function defaultSettings() {
    return [
      'toolbar' => [
        'position' => 'top',
        'drawPoint' => TRUE,
        'editMode' => TRUE,
        'deleteMode' => TRUE,
      ],
    ] + parent::defaultSettings();
  }

  /**
   * {@inheritdoc}
   */
  public function settingsForm(array $form, FormStateInterface $form_state) {
    $settings = $this
      ->getSettings();
    $form = parent::settingsForm($form, $form_state);
    $form['toolbar']['DrawPoint'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Adds button to draw point markers.'),
      '#default_value' => $settings['toolbar']['DrawPoint'],
    ];
    $form['toolbar']['Modify'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Adds button to edit features.'),
      '#default_value' => $settings['toolbar']['Modify'],
    ];
    $form['toolbar']['Delete'] = [
      '#type' => 'checkbox',
      '#title' => $this
        ->t('Adds button to delete features.'),
      '#default_value' => $settings['toolbar']['Delete'],
    ];
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function settingsSummary() {
    $summary = [];
    $map_label = \Drupal::config('openlayers.map.' . $this
      ->getSetting('map'))
      ->get('label');
    $summary[] = $this
      ->t('Openlayers map: @map', [
      '@map' => $map_label,
    ]);
    $summary[] = $this
      ->t('Map height: @height @height_unit', [
      '@height' => $this
        ->getSetting('height'),
      '@height_unit' => $this
        ->getSetting('height_unit'),
    ]);
    return $summary;
  }

  /**
   * {@inheritdoc}
   */
  public function formElement(FieldItemListInterface $items, $delta, array $element, array &$form, FormStateInterface $form_state) {
    $element['#type'] = 'fieldset';
    $element['lat'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('Latitude'),
      '#default_value' => isset($items[$delta]->lat) ? $items[$delta]->lat : NULL,
      '#empty_value' => '',
      '#maxlength' => 255,
      '#required' => $this->fieldDefinition
        ->isRequired(),
    ];
    $lat_example = $element['lat']['#default_value'] ?: '51.47879';
    $element['lat']['#description'] = $this
      ->t('Enter either in decimal %decimal or sexagesimal format %sexagesimal', [
      '%decimal' => $lat_example,
      '%sexagesimal' => GeolocationItem::decimalToSexagesimal($lat_example),
    ]);
    $element['lng'] = [
      '#type' => 'textfield',
      '#title' => $this
        ->t('Longitude'),
      '#empty_value' => '',
      '#default_value' => isset($items[$delta]->lng) ? $items[$delta]->lng : NULL,
      '#maxlength' => 255,
      '#required' => $this->fieldDefinition
        ->isRequired(),
    ];
    $lng_example = $element['lng']['#default_value'] ?: '-0.010677';
    $element['lng']['#description'] = $this
      ->t('Enter either in decimal %decimal or sexagesimal format %sexagesimal', [
      '%decimal' => $lng_example,
      '%sexagesimal' => GeolocationItem::decimalToSexagesimal($lng_example),
    ]);

    // Attach class to wkt input element, so we can find it in js/openlayers.js.
    $field_name = $this->fieldDefinition
      ->getName();
    $element_name = str_replace('_', '-', $field_name) . '-' . $delta;
    $element['value']['#attributes']['class'][] = $element_name;

    // Determine map settings and add map element.
    $settings = $this
      ->getSettings();
    $map = new MapSettings($settings['map']);
    $cache_tags = $map->cacheTags;
    $map = $map->settings;

    // Add a specific map id.
    $map['id'] = 'openlayers-map-' . str_replace('_', '-', $field_name) . '-' . $delta;
    $js_settings = [
      'map' => $map,
      'features' => [],
    ];
    $toolbar = !empty($this
      ->getSetting('toolbar')) ? $this
      ->getSetting('toolbar') : [];
    $toolbar['DrawLine'] = false;
    $toolbar['DrawPolygon'] = false;
    $toolbar['DrawHole'] = false;

    // Build JS settings for Openlayers widget.
    $js_settings['map_id'] = $map['id'];
    $js_settings['widget']['fieldType'] = 'geolocation';
    $js_settings['widget']['valueElement'] = $element_name;
    $cardinality = $items
      ->getFieldDefinition()
      ->getFieldStorageDefinition()
      ->getCardinality();
    $js_settings['multiple'] = $cardinality == 1 ? FALSE : TRUE;
    $js_settings['cardinality'] = $cardinality > 0 ? $cardinality : 0;
    $js_settings['widget']['inputShow'] = intval($settings['input']['show']);
    $js_settings['widget']['inputEditable'] = intval($settings['input']['editable']);
    $js_settings['widget']['toolbarSettings'] = $toolbar;
    $js_settings['widget']['center_zoom']['lat'] = floatval($settings['initial_settings']['lat']);
    $js_settings['widget']['center_zoom']['lon'] = floatval($settings['initial_settings']['lon']);
    $js_settings['widget']['center_zoom']['zoom'] = floatval($settings['initial_settings']['zoom']);
    $element['map'] = $this->openlayersService
      ->openlayersRenderMap($js_settings, $settings['height'] . $settings['height_unit'], $cache_tags);
    $element['map']['#weight'] = -1;
    $element['map']['#attached']['library'][] = 'openlayers/openlayers-widget';

    // Settings and geo-data are passed to the widget keyed by field id.
    $element['map']['#attached']['drupalSettings']['openlayers_widget'] = [
      $element['map']['#map_id'] => $js_settings,
    ];
    return $element;
  }

  /**
   *
   */
  public function getFieldDefinition() {
    return $this->fieldDefinition;
  }

}

Classes

Namesort descending Description
OpenlayersGeolocationWidget Plugin implementation of an Openlayers widget.