openlayers-8.x-4.x-dev/src/Plugin/Control/LayerSwitcher/LayerSwitcher.php

src/Plugin/Control/LayerSwitcher/LayerSwitcher.php
<?php

namespace Drupal\openlayers\Plugin\Control\LayerSwitcher;

use Drupal\Core\Form\FormStateInterface;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Component\Utility\Html;

use Drupal\openlayers\Types\Control;
use Drupal\openlayers\Types\ObjectInterface;
use Drupal\openlayers\Openlayers;

/**
 * Defines the Layer Switcher control for an Openlayers map.
 *
 * @OpenlayersPlugin(
 *   id = "ol_control_layerswitcher",
 *   label = @Translation("Layer switcher"),
 *   description = @Translation("Define a layer switcher control."),
 *   service = "openlayers.Control:LayerSwitcher",
 *   library = "openlayers-plugin-control-layerswitcher",
 *   is_configurable = "true",
 *   type = "control"
 * )
 */
class LayerSwitcher extends Control {

  /**
   * {@inheritdoc}
   */
  public function getSummary() {
    $summary = [
      '#theme' => 'openlayers_control_summary',
      '#data' => $this->configuration,
    ];
    $summary += parent::getSummary();

    return $summary;
  }

  /**
   * {@inheritdoc}
   */
  public function defaultConfiguration() {
    return [
      'label' => 'Label XX',
      'layers' => [],
      'className' => 'ol-layerswitcher-XX',
      'multiselect' => true,
    ];
  }

  /**
   * {@inheritdoc}
   */
  public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
    foreach($form['options'] as $key => $item) {
      $this->configuration[$key] = $form['options'][$key];
    }

    // Get, decorate and order all layers.
    $all_layers = Openlayers::loadAllAsOptions('Layer');
    foreach ($all_layers as $machine_name => $name) {
      $selected = TRUE;
      if (($layer = Openlayers::load('Layer', $machine_name)) == TRUE)
        $selected = $layer->getOption('visible', 1) != 0;
      $all_layers[$machine_name] = array('name' => $name,
//                                         'weight' => PHP_INT_MAX,   //  TODO
                                         'weight' => 0,
                                         'label' => $name,
                                         'selected' => $selected,
                                         'enabled' => FALSE,
                                        );
    }
    $all_layers = array_merge($all_layers, $this->getOptionLayers());
    uasort($all_layers, function($a, $b) {
      if ($a['enabled'] != $b['enabled'])
        return $a['enabled']? -1: 1;
      if ($a['weight'] != $b['weight'])
        return $a['weight'] - $b['weight'];
      if ($a['name'] != $b['name'])
        return strcmp($a['name'], $b['name']);
      return strcmp($a['name'], $b['name']);
    });


    // Build layers table.
    $rows = array();
    $weight = 0;

    // Build form.

    $form['options']['label'] = array(
      '#type' => 'textfield',
      '#title' => t('Title of the control'),
      '#default_value' => isset($this->configuration['label']) ? $this->configuration['label'] : 'Layers',
    );

    $form['options']['multiselect'] = array(
      '#type' => 'checkbox',
      '#title' => t('Allow selecting multiple layers'),
      '#default_value' => isset($this->configuration['multiselect']) ? $this->configuration['multiselect'] : false,
    );

    $form['options']['className'] = [
      '#type' => 'textfield',
      '#default_value' => isset($this->configuration['className']) ? $this->configuration['className'] : '',
      '#title' => t('Class name'),
      '#description' => t('CSS class name.'),
      '#size' => 50,
      '#maxlength' => 50,
      '#required' => FALSE,
    ];

    $form['options']['layers'] = array(
      '#type' => 'table',
      '#header' => array(
        'name' => t('Name'),
        'enabled' => t('Enabled'),
        'label' => t('Label'),
        'selected' => t('Selected'),
        'weight' => t('Weight'),
      ),
      '#empty' => t('There are no entries available.'),
      '#sticky' => TRUE,
      
      //    drupal_add_tabledrag('layerswitcher-order', 'order', 'sibling', 'layerswitcher-order-weight');    //  TODO - replace drupal_add_tabledrag
      
      // Properties for tabledrag support.
      // The value is a list of arrays that are passed to
      // drupal_attach_tabledrag(). Table::preRenderTable() prepends the HTML ID
      // of the table to each set of options.
      // @see drupal_attach_tabledrag()
      
      // TableDrag: Each array value is a list of callback arguments for
      // drupal_add_tabledrag(). The #id of the table is automatically
      // prepended; if there is none, an HTML ID is auto-generated.
      '#tabledrag' => [
        [
          'action' => 'order',
          'relationship' => 'sibling',
          'group' => 'table-sort-weight',
        ],
      ],
    );
    
    // Build the table rows and columns.
    foreach ($all_layers as $id => $layer) {

      if (isset($this->configuration['layers'][$id])) {
        $config = $this->configuration['layers'][$id];
      } else {
        $config = [];
      }

      $form['options']['layers'][$id]['#attributes']['class'][] = 'draggable';

      // TableDrag: Sort the table row according to its existing/configured
      // weight.
      $form['options']['layers'][$id]['#weight'] = isset($config['weight']) ? $config['weight'] : $layer['weight'];

     // Some table columns containing raw markup.
      $form['options']['layers'][$id]['name'] = [
        '#markup' => $layer['name'],
      ];

      $form['options']['layers'][$id]['enabled'] = [
        '#type' => 'checkbox',
        '#default_value' => isset($config['enabled']) ? $config['enabled'] : $layer['enabled'],
      ];
      
      $form['options']['layers'][$id]['label'] = [
        '#type' => 'textfield',
        '#required' => TRUE,
        '#default_value' => isset($config['label']) ? $config['label'] : $layer['label'],
      ];
      
      $form['options']['layers'][$id]['selected'] = [
        '#type' => 'checkbox',
        '#default_value' => isset($config['selected']) ? $config['selected'] : $layer['selected'],
      ];

      // TableDrag: Weight column element.
      $form['options']['layers'][$id]['weight'] = [
        '#type' => 'weight',
        '#title' => $this
          ->t('Weight for @title', [
          '@title' => $layer['name'],
        ]),
        '#title_display' => 'invisible',
        '#default_value' => isset($config['weight']) ? $config['weight'] : $layer['weight'],
        // Classify the weight element for #tabledrag.
        '#attributes' => [
          'class' => [
            'table-sort-weight',
          ],
        ],
      ];
    }

    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {

  }

  /**
   * {@inheritdoc}
   */
  public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {

    foreach($form_state->getValues() as $key => $item) {
      $this->configuration[$key] = $form_state->getValue($key);
    }

    // Process labels i18n updates, order layers and drop unneeded values.
    if ($form_state->getValue('options') !== null) {
      $all_layers = Openlayers::loadAllAsOptions('Layer');
      $options = &$form_state->getValue('options');
      if (isset($options['layers'])) {
        $layers = &$options['layers'];
        uasort($layers, function($a, $b) {
          if ($a['enabled'] != $b['enabled'])
            return $a['enabled']? -1: 1;
          return $a['weight'] - $b['weight'];
        });
        foreach ($layers as $id => $layer) {
          $label = '';
          if (!$layer['enabled'])
            unset($layers[$id]);
          else {
            $label = $layer['label'];
            if ($label == '')
              $label = isset($all_layers[$id])? $all_layers[$id]: $id;
            unset($layers[$id]['weight']);
            unset($layers[$id]['enabled']);
          }
        }
      }
    }
  }


  /**
   * {@inheritdoc}
   */
  public function preBuild(array &$build, ObjectInterface $context = NULL) {
    $map_id = $context->getId();
    $layers = $this->getOptionLayers();
    $items = array();
    $map_layers = array();
    foreach ($context->getObjects('layer') as $map_layer)
      $map_layers[$map_layer->getMachineName()] = $map_layer;

    $multiselect = $this->getOption('multiselect', FALSE);
    $element_type = $multiselect ? 'checkbox' : 'radio';

    // Only handle layers available in the map and configured in the control.
    // @TODO: use Form API (with form_process_* and stuff)
    $selection = FALSE;
    foreach ($layers as $id => $layer) {
      if (!isset($map_layers[$id]))
        unset($layers[$id]);
      else if ($layer['selected']) {
        if (!$multiselect && $selection)
          $layers[$id]['selected'] = FALSE;
        $selection = TRUE;
      }
    }
    if (!$multiselect && !$selection) {
      foreach ($layers as $id => $layer) {
        $layers[$id]['selected'] = TRUE;
        break;
      }
    }
    foreach ($layers as $id => $layer) {
      $classes = array(Html::getClass($id));
      $checked = $layer['selected']? 'checked="checked" ': '';
//      $label = openlayers_i18n_string('openlayers:layerswitcher:' . $this->getMachineName() . ':' . $id . ':label', $layer['label'], array('sanitize' => TRUE));
      $label = $layer['label'];        //  TODO temp line
      $items[] = array(
//        'data' => '<label><input type="' . $element_type . '" name="layer" ' . $checked . 'value="' . $id . '">' . $label . '</label>',
        '#markup' => '<label><input type="' . $element_type . '" name="layer" ' . $checked . 'value="' . $id . '">' . $label . '</label>',
//        'id' => Html::getUniqueId($map_id . '-' . $id),
//        'class' => $classes,
        '#attributes' => ['id' => Html::getUniqueId($map_id . '-' . $id), 'class' => $classes],
      );
    }

    $layerswitcher = array(
      '#theme' => 'item_list',
      '#type' => 'ul',
      '#items' => $items,
      '#attributes' => array(
        'id' => Html::getUniqueId($this->getMachineName() . '-items'),
      ),
    );

    $title = $this->getOption('options')['label'];
    if ($title != '<none>') {
//      $title = openlayers_i18n_string('openlayers:layerswitcher:' . $this->getMachineName() . ':title', $title, array('sanitize' => TRUE));   //  TODO
      $layerswitcher['#title'] = $title;
    }
    $this->setOption('element', '<div id="' . Html::getUniqueId($this->getMachineName()) . '" class="' . Html::getClass($this->getMachineName()) . ' layerswitcher">' . \Drupal::service('renderer')->renderPlain($layerswitcher) . '</div>');

    // Allow the parent class to perform it's pre-build actions.
    parent::preBuild($build, $context);
  }

  /**
   * Get layers from options, converting them from old storage style if
   * needed and decorating them with additional properties.
   */
  private function getOptionLayers() {

    $option_layers = $this->getOptions()['options']['layers'];

    $labels = $this->getOption('layer_labels', array());
    $layers = array();
    $weight = 0;

    foreach ($option_layers as $machine_name => $params) {
      $name = $machine_name;
      $selected = TRUE;
      if (($map_layer = Openlayers::load('Layer', $machine_name)) == TRUE) {
        $name = $map_layer->getName();
        $selected = $map_layer->getOption('visible', 1) != 0;
      }

      if (!is_array($params)) {    /* Old-style options. */
        $label = isset($labels[$machine_name])? $labels[$machine_name]: $name;
        $params = array('label' => $label, 'selected' => $selected);
      }

      $params['name'] = $name;
      $params['enabled'] = TRUE;
      $params['weight'] = $weight++;

      $layers[$machine_name] = $params;
    }

    return $layers;
  }

}

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

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