geolocation-8.x-3.x-dev/src/Element/GeolocationMap.php

src/Element/GeolocationMap.php
<?php

namespace Drupal\geolocation\Element;

use Drupal\Component\Utility\SortArray;
use Drupal\Core\Render\BubbleableMetadata;
use Drupal\Core\Render\Element;
use Drupal\Core\Render\Element\RenderElementBase;
use Drupal\Core\Template\Attribute;
use Drupal\geolocation\MapProviderManager;

/**
 * Provides a render element to display a geolocation map.
 *
 * Usage example:
 * @code
 * $form['map'] = [
 *   '#type' => 'geolocation_map',
 *   '#prefix' => $this->t('Geolocation Map Render Element'),
 *   '#description' => $this->t('Render element type "geolocation_map"'),
 *   '#maptype' => 'leaflet,
 *   '#centre' => [],
 *   '#id' => 'thisisanid',
 * ];
 * @endcode
 *
 * @RenderElement("geolocation_map")
 */
class GeolocationMap extends RenderElementBase {

  /**
   * Map Provider.
   *
   * @var \Drupal\geolocation\MapProviderManager
   */
  protected MapProviderManager $mapProviderManager;

  /**
   * {@inheritdoc}
   */
  public function __construct(array $configuration, $plugin_id, $plugin_definition) {
    parent::__construct($configuration, $plugin_id, $plugin_definition);

    $this->mapProviderManager = \Drupal::service('plugin.manager.geolocation.mapprovider');
  }

  /**
   * {@inheritdoc}
   */
  public function getInfo(): array {
    $class = get_class($this);

    return [
      '#process' => [
        [$class, 'processGroup'],
      ],
      '#pre_render' => [
        [$class, 'preRenderGroup'],
        [$this, 'preRenderMap'],
      ],
      '#maptype' => NULL,
      '#centre' => NULL,
      '#id' => NULL,
      '#controls' => NULL,
      '#layers' => [],
      '#context' => [],
    ];
  }

  /**
   * Map element.
   *
   * @param array $render_array
   *   Element.
   *
   * @return array
   *   Renderable map.
   */
  public function preRenderMap(array $render_array): array {
    $render_array['#theme'] = 'geolocation_map_wrapper';

    $render_array['#cache'] = array_merge_recursive(
      $render_array['#cache'] ?? [],
      ['contexts' => ['languages:language_interface']]
    );

    if (empty($render_array['#id'])) {
      $render_array['#id'] = uniqid('map-');
    }

    if (!empty($render_array['#controls'])) {
      uasort($render_array['#controls'], [
        SortArray::class,
        'sortByWeightProperty',
      ]);
    }

    if (!empty($render_array['#children'])) {
      uasort($render_array['#children'], [
        SortArray::class,
        'sortByWeightProperty',
      ]);
    }

    if (empty($render_array['#maptype'])) {
      if (\Drupal::moduleHandler()->moduleExists('geolocation_google_maps')) {
        $render_array['#maptype'] = 'google_maps';
      }
      elseif (\Drupal::moduleHandler()->moduleExists('geolocation_leaflet')) {
        $render_array['#maptype'] = 'leaflet';
      }
    }

    $map_provider = $this->mapProviderManager->getMapProvider($render_array['#maptype']);
    if (empty($map_provider)) {
      return $render_array;
    }

    $map_settings = [];
    if (
      !empty($render_array['#settings'])
      && is_array($render_array['#settings'])
    ) {
      $map_settings = $render_array['#settings'];
    }

    $map_settings = $map_provider->getSettings($map_settings);

    $render_array = BubbleableMetadata::mergeAttachments(
      [
        '#attached' => [
          'library' => [
            'geolocation/geolocation.map',
          ],
        ],
      ],
      $render_array
    );

    $render_array['#attributes'] = new Attribute($render_array['#attributes'] ?? []);
    $render_array['#attributes']->addClass('geolocation-map-wrapper');
    $render_array['#attributes']->setAttribute('id', $render_array['#id']);
    $render_array['#attributes']->setAttribute('data-map-type', $render_array['#maptype']);

    if (
      !empty($render_array['#centre']['lat'])
      && !empty($render_array['#centre']['lng'])
    ) {
      $render_array['#attributes']->setAttribute('data-lat', $render_array['#centre']['lat']);
      $render_array['#attributes']->setAttribute('data-lng', $render_array['#centre']['lng']);
    }

    if (
      !empty($render_array['#centre']['lat_north_east'])
      && !empty($render_array['#centre']['lng_north_east'])
      && !empty($render_array['#centre']['lat_south_west'])
      && !empty($render_array['#centre']['lng_south_west'])
    ) {
      $render_array['#attributes']->setAttribute('data-centre-lat-north-east', $render_array['#centre']['lat_north_east']);
      $render_array['#attributes']->setAttribute('data-centre-lng-north-east', $render_array['#centre']['lng_north_east']);
      $render_array['#attributes']->setAttribute('data-centre-lat-south-west', $render_array['#centre']['lat_south_west']);
      $render_array['#attributes']->setAttribute('data-centre-lng-south-west', $render_array['#centre']['lng_south_west']);
    }

    $context = [];
    if (!empty($render_array['#context'])) {
      $context = $render_array['#context'];
    }

    $render_array = $map_provider->alterRenderArray($render_array, $map_settings, $context);

    if (is_array($render_array['#layers'] ?? FALSE)) {
      foreach (Element::children($render_array['#layers']) as $layer_id) {
        $render_array['#children'][$layer_id] = $render_array['#layers'][$layer_id];
        unset($render_array['#layers'][$layer_id]);
      }
    }

    foreach (Element::children($render_array) as $child) {
      $render_array['#children'][$child] = $render_array[$child];
      unset($render_array[$child]);
    }

    return $render_array;
  }

  /**
   * Recursively return all locations in render array.
   *
   * @param array $render_array
   *   Geolocation Map render array.
   *
   * @return array
   *   Geolocation Map Locations.
   */
  public static function getLocations(array $render_array): array {
    $locations = [];
    if (
      !empty($render_array['#type'])
      && $render_array['#type'] == 'geolocation_map_location'
    ) {
      $locations[] = $render_array;
    }
    elseif (!empty($render_array['#children'])) {
      foreach ($render_array['#children'] as $child) {
        if (is_array($child)) {
          $locations = array_merge($locations, static::getLocations($child));
        }
      }
    }
    else {
      foreach (Element::children($render_array) as $key) {
        if (is_array($render_array[$key])) {
          $locations = array_merge($locations, static::getLocations($render_array[$key]));
        }
      }
    }

    return $locations;
  }

}

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

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