You are here

public function IpGeoLocViewsPluginStyle::pluginStyleBulkOfForm in IP Geolocation Views & Maps 8

The bulk of the plugin style form.

File

src/Services/IpGeoLocViewsPluginStyle.php, line 53

Class

IpGeoLocViewsPluginStyle
Class IpGeoLocViewsPluginStyle.

Namespace

Drupal\ip_geoloc\Services

Code

public function pluginStyleBulkOfForm($views_plugin_style, &$form, FormStateInterface &$form_state) {

  // We only ever want to offer at most 1 grouping field.
  if (!empty($form['grouping']) && count($form['grouping']) > 1) {
    $form['grouping'] = array_slice($form['grouping'], 0, 1);
  }
  $fields = ip_geoloc_get_display_fields($views_plugin_style->displayHandler, TRUE);
  $field_options = $fields;
  $field_options['---'] = '[' . t('Type a field name') . ']';
  $selected_option = $views_plugin_style->options['ip_geoloc_views_plugin_latitude'];
  if (!isset($field_options[$selected_option])) {
    $selected_option = '---';
  }
  $form['ip_geoloc_views_plugin_latitude'] = [
    '#title' => t('Name of latitude field in Views query'),
    '#type' => 'select',
    '#options' => $field_options,
    '#default_value' => $selected_option,
    '#weight' => 10,
  ];
  $form['ip_geoloc_views_plugin_latitude_text'] = [
    '#type' => 'textfield',
    '#default_value' => $views_plugin_style->options['ip_geoloc_views_plugin_latitude'],
    '#states' => [
      'visible' => [
        ':input[name="style_options[ip_geoloc_views_plugin_latitude]"]' => [
          'value' => '---',
        ],
      ],
    ],
    '#weight' => 11,
  ];
  $form['ip_geoloc_views_plugin_latitude_desc'] = [
    '#type' => 'item',
    '#markup' => t('Select the field holding the latitude from the dropdown above.<br/><strong>Special cases</strong> If the View has relationships and lat/lon are accessed via the relationships, select <em>[Type field name]</em> and enter the field name in the additional text box presented. If you use a view based on the <strong>Location</strong> module, enter <strong>location_latitude</strong>. If the latitude is stored in a <strong>field</strong>, then enter the field\'s machine name. For instance, when using the <strong>Geofield</strong>, <strong>Geolocation field</strong> or <strong>Get Locations</strong> modules enter <strong>field_<em>yourfieldname</em></strong>. If necessary, check the <a target="_field_names" href="!url">list of all field names</a>. <br/>For IP Geolocation Views & Maps <em>visitor</em> data, enter <strong>ip_geoloc_latitude</strong>.', [
      '!url' => 'admin/reports/fields',
    ]),
    '#weight' => 12,
  ];
  $selected_option = $views_plugin_style->options['ip_geoloc_views_plugin_longitude'];
  if (!isset($field_options[$selected_option])) {
    $selected_option = '---';
  }
  $form['ip_geoloc_views_plugin_longitude'] = [
    '#title' => t('Name of longitude field in Views query'),
    '#type' => 'select',
    '#options' => $field_options,
    '#default_value' => $selected_option,
    '#weight' => 15,
  ];
  $form['ip_geoloc_views_plugin_longitude_text'] = [
    '#type' => 'textfield',
    '#default_value' => $views_plugin_style->options['ip_geoloc_views_plugin_longitude'],
    '#states' => [
      'visible' => [
        ':input[name="style_options[ip_geoloc_views_plugin_longitude]"]' => [
          'value' => '---',
        ],
      ],
    ],
    '#weight' => 16,
  ];
  $form['ip_geoloc_views_plugin_longitude_desc'] = [
    '#type' => 'item',
    '#markup' => t('See comments above. When using the <strong>Geofield</strong>, <strong>Geolocation field</strong> or <strong>Get Locations</strong> modules select <em>&lt;none&gt;</em>.'),
    '#weight' => 17,
  ];
  $differentiator = $form_state
    ->getValue('differentiator') ? $form_state
    ->getValue('differentiator') : $views_plugin_style->options['differentiator']['differentiator_field'];
  $user_input = $form_state
    ->getUserInput();
  if (isset($user_input["color_table"])) {
    $form_state
      ->set('num_associations', count($user_input["color_table"]));
  }

  //@TODO check on change even to see if this is necessary
  if (isset($user_input["_triggering_element_name"]) && $user_input["_triggering_element_name"] == "style_options[differentiator][differentiator_field]") {

    // Get here when any form element with #ajax was changed/clicked causing
    // an auto-rebuild of the form. Can't put this in an ajax handler, as these
    // are called AFTER the form rebuild, so too late.
    // @TODO check how to migrate this
    // if (strpos($form_state->getTriggeringElement()['#id'], 'differentiator-differentiator-field') > 0) {
    // Get here when it was the differentiator drop-down that was changed.
    $differentiator = $user_input['style_options']['differentiator']['differentiator_field'];

    //$form_state->set('num_associations', NULL);

    // }
  }
  $form_state
    ->set('differentiator', $differentiator);

  // Or AJAX won't work!
  $form_state
    ->disableCache();
  $is_openlayers = TRUE;
  $form_state
    ->set('renderer', 'openlayers');
  $form['default_marker_color'] = [
    '#title' => t('Default location marker'),
    '#type' => 'select',
    '#default_value' => $views_plugin_style->options['default_marker_color'],
    '#options' => $is_openlayers ? $this->ipGeolocGlobal
      ->openlayersMarkerLayers() : $this->ipGeolocGlobal
      ->markerColors(),
    '#description' => t('Select an image to use for all location markers whose images are not overridden by the <strong>location differentiator</strong> below.'),
    '#attributes' => [
      'class' => $is_openlayers ? [
        'marker-color-ol',
      ] : [
        'marker-color',
      ],
    ],
    '#weight' => 20,
  ];
  if (!$is_openlayers) {
    $path = drupal_get_path('module', 'ip_geoloc');
    $css_file = strpos($this->config
      ->get('ip_geoloc_marker_directory'), 'amarkers') ? 'ip_geoloc_admin_a.css' : 'ip_geoloc_admin.css';
    $form['default_marker_color']['#attached']['css'] = [
      "{$path}/css/{$css_file}",
    ];
  }

  // Add wrapper for differentiator drop-down, association table and buttons.
  // The id in the prefix must match the AJAX submit handlers below.
  $desc = t('You may designate one field from your view as a <strong>location differentiator</strong>. Locations that match the same corresponding differentiator value will have the same marker image on the map. Examples of location differentiators are content type and taxonomy term. You can enter numeric and alphabetic <em>ranges</em> too, e.g. price ranges, like 100--125.<br/><strong>Leaflet</strong> only: you may input a special character, eg. from <a target="_fsymbols" href="!url1">fsymbols</a> or <a target="_font_awesome" href="!url2">Font Awesome</a>, to be superimposed as a font-icon on the marker image. For <em>fsymbols</em> copy and paste the desired font-icon into the Special Char field. For <em>Font Awesome</em> icons leave the Special Char field empty. Instead type the <em>Font Awesome</em> icon name in the Special Char CSS Class field, optionally appending a color class. Example: <strong>icon-beer icon-light</strong>. <br/>All this works best with the markers from the <em>/amarkers</em> directory, configurable <a target="_ip_geoloc_config" href="!url3">here</a>.', [
    /*'!url1' => url('http://fsymbols.com'),
      '!url2' => url('http://fortawesome.github.io/Font-Awesome/cheatsheet'),
      '!url3' => url('admin/config/system/ip_geoloc'),*/
    '!url1' => 'http://fsymbols.com',
    '!url2' => 'http://fortawesome.github.io/Font-Awesome/cheatsheet',
    '!url3' => 'admin/config/system/ip_geoloc',
  ]);
  $form['differentiator'] = [
    '#type' => 'fieldset',
    '#title' => t('Location differentiator and associated markers'),
    '#description' => $desc,
    '#prefix' => '<div id="differentiator-wrapper">',
    '#suffix' => '</div>',
    '#weight' => 30,
  ];

  // @TODO Check this function implementaton to get the field name
  if (empty($differentiator)) {
    $description = t('Optionally select a location differentiator.');
  }
  else {

    // $instances = ip_geoloc_get_field_instances($differentiator);
    // $instance = reset($instances);
    // @TODO migrate this field. Get entity type
    // $field = field_info_field($differentiator);
    // Remove node and get the info from related view entity type, take care of taxonomies
    $field = FieldStorageConfig::loadByName('node', $differentiator);
    $description = t('Below associate %differentiator values with marker images.', [
      '%differentiator' => $field
        ->getLabel(),
    ]) . '<br/>';
    if (!$field || $field
      ->getType() == 'text') {
      $description .= t('You may enter a range of values by separating "from" and "to" by a <strong>double hyphen</strong>.<br/>Example: <strong>A--ZZ</strong><br/>You may omit "from" or "to" to create open-ended ranges.');
    }
    elseif ($field
      ->getType() == 'number') {
      $description .= t('You may enter a numeric range of by separating "from" and "to" by a <strong>double hyphen</strong>.<br/>Example: <strong>2.5--7.95</strong><br/>You may omit "from" or "to" to create open-ended ranges.');
    }
  }
  $form['differentiator']['differentiator_field'] = [
    '#title' => t('Location differentiator'),
    '#type' => 'select',
    '#default_value' => $differentiator,
    '#options' => $fields,
    '#description' => $description,
    '#ajax' => [
      'callback' => [
        $this,
        'pluginStyleRefreshColorTableJs',
      ],
      'wrapper' => 'differentiator-wrapper',
      'prevent' => 'submit',
    ],
  ];
  if (!empty($differentiator)) {

    // Container for the differentiator color associations table.
    $field = FieldStorageConfig::loadByName('node', $differentiator);
    $differentiator_label = $field
      ->getLabel();
    $header = [
      $differentiator_label,
      t('Associated marker image'),
      t('Special char'),
      t('Special char CSS class'),
    ];
    $form['differentiator']['color_table'] = [
      //'#theme' => 'ip_geoloc_plugin_style_differentiator_color_table',
      '#type' => 'table',
      '#header' => $header,
      '#rows' => [],
      '#tree' => TRUE,
      '#attributes' => [
        'id' => 'differentiator-color-table',
      ],
    ];
    if (isset($user_input["_triggering_element_value"]) && !empty($user_input["_triggering_element_value"])) {
      if ($user_input["_triggering_element_value"] == t("Add another association") || $user_input["_triggering_element_value"] == t("Add an association")) {
        $this
          ->pluginStyleAddAssociationSubmit($form, $form_state);
        $this
          ->pluginStyleDifferentiatorColorAssociationsSubmit($form, $form_state);
      }
      if ($user_input["_triggering_element_value"] == t("Remove bottom association")) {
        $this
          ->pluginStyleRemoveAssociationSubmit($form, $form_state);
        $this
          ->pluginStyleDifferentiatorColorAssociationsSubmit($form, $form_state);
      }
    }

    // Saving color configuration data
    if ($user_input["op"] == t("Apply")) {
      $this
        ->pluginStyleDifferentiatorColorAssociationsSubmit($form, $form_state);
    }
    $this
      ->pluginStyleDifferentiatorColorTableForm($form, $form_state);
    $form['differentiator']['add-another'] = [
      '#type' => 'submit',
      '#value' => empty($form_state
        ->get('num_associations')) ? t('Add an association') : t('Add another association'),
      '#weight' => 1,
      //'#submit' => [$this,'pluginStyleDifferentiatorColorAssociationsSubmit'],
      '#ajax' => [
        'callback' => [
          $this,
          'pluginStyleRefreshColorTableJs',
        ],
        'wrapper' => 'differentiator-wrapper',
        // Or 'none' or 'slide'.
        'effect' => 'fade',
        // Or 'slow' or number of millisec.
        'speed' => 'fast',
        'prevent' => 'submit',
      ],
    ];
    if (!empty($form_state
      ->get('num_associations'))) {
      $form['differentiator']['remove'] = [
        '#type' => 'submit',
        '#value' => t('Remove bottom association'),
        '#weight' => 2,
        '#ajax' => [
          'callback' => [
            $this,
            'pluginStyleRefreshColorTableJs',
          ],
          'wrapper' => 'differentiator-wrapper',
          // Or 'fade' or 'slide'.
          'effect' => 'none',
          // Or 'slow' or number of millisec.
          'speed' => 'fast',
          'prevent' => 'submit',
        ],
      ];
    }
  }
  if ($is_openlayers) {
    $desc = t('*) If you want a fixed center, visit the "Center & Bounds" vertical tab on the <a target="_ol_map_edit" href="@url">map edit page</a>. This is also where you set the initial zoom level.', [
      // '@url' => url('admin/structure/openlayers/maps/' . $views_plugin_style->options['map'] . '/edit'),.
      '@url' => 'admin/structure/openlayers/maps/' . $views_plugin_style->options['map'] . '/edit',
    ]);
  }
  else {
    $desc = t('*) If you choose the first option you may center the map via the special <strong>Map options</strong> <em>"centerLat"</em> and <em>"centerLng"</em> for example:<br/>%center_example', [
      '%center_example' => '{ "mapTypeId":"terrain", "centerLat":-37.8, "centerLng":145 }',
    ]);
  }
  $form['center_option'] = [
    '#title' => t('Map centering options'),
    '#type' => 'radios',
    '#default_value' => $views_plugin_style->options['center_option'],
    '#options' => [
      IP_GEOLOC_MAP_CENTER_FIXED => t('Fixed center; see note below *)'),
      IP_GEOLOC_MAP_CENTER_ON_FIRST_LOCATION => t('Use the first location returned by the view as the center of the map.'),
      IP_GEOLOC_MAP_CENTER_ON_VISITOR => t("Center the map on the visitor's current location."),
      IP_GEOLOC_MAP_CENTER_OF_LOCATIONS => t('Use the center of the rectangle whose sides are defined by the left-most, right-most, top and bottom locations (this option is insensitive to location clusters).'),
      IP_GEOLOC_MAP_CENTER_OF_LOCATIONS_WEIGHTED => t('Use the center of gravity based on all locations (this option is sensitive to location clusters)'),
    ],
    '#description' => $desc,
    '#weight' => 40,
  ];
  $form['empty_map_center'] = [
    '#title' => t('No locations behaviour'),
    '#type' => 'textfield',
    '#size' => 30,
    '#default_value' => $views_plugin_style->options['empty_map_center'],
    '#description' => t('a) Show empty map: enter <em>latitude, longitude</em> of the map center.<br/>b) Show empty map centered on visitor location: enter the word %visitor.<br/>c) Show nothing: if this field is left blank, the map canvas will be suppressed when there are no locations to show. If you wish, you may use the <strong>No results behavior</strong> panel in the Advanced section of the Views UI to show an alternative text or content.', [
      '%visitor' => t('visitor'),
    ]),
    '#weight' => 110,
  ];
  return $form;
}