You are here

public function IpGeoLocAPI::outputMapMultiLocation in IP Geolocation Views & Maps 8

Outputs an HTML div placeholder into which will be injected a Google map.

The locations to be mapped are supplied as an array of location objects, each with lat,long coordinates and optional balloon text.

Note this function will result in the visitor being prompted to share their location.

Parameters

array $locations: Array of location objects each containing lat/long pair and optional balloon text.

string $div_id: Id of the div placeholder, can be anything as long as it's unique.

string $map_options: As a JSON string, .e.g '{"mapTypeId":"roadmap", "zoom":15}'.

string $map_style: CSS style applied to the div, e.g "height:250px; width:300px".

string $marker_color: Default color used for all locations that haven't had their color overridden, defaults to Google default (i.e. red marker with dot).

bool|string $visitor_marker: FALSE (no marker), TRUE (standard red marker) or a 'RRGGBB' color code.

int $center_option: Value 0: fixed cenrer, must be provided thorugh $map_options) Value 1: auto-center the map on the first location in the $locations array Value 2: auto-center the map on the visitor's current location.

array $center_latlng: Array of length 2 with lat/long coords used as a backup when $visitor_marker is set or $center_option == 2 and location could not be determined or $visitor_location_gps == FALSE.

bool $visitor_location_gps: Whether the HTML5-style location provider is to be used, if FALSE $center_latlng is used.

Return value

string Map placeholder div.

File

src/Services/IpGeoLocAPI.php, line 238

Class

IpGeoLocAPI
Class IpGeoAPI to interact with other modules.

Namespace

Drupal\ip_geoloc\Services

Code

public function outputMapMultiLocation(array $locations, $div_id = 'ip-geoloc-map-multi-locations', $map_options = NULL, $map_style = NULL, $marker_color = NULL, $visitor_marker = TRUE, $center_option = 0, array $center_latlng = [
  0,
  0,
], $visitor_location_gps = TRUE) {
  if (!isset($map_options)) {
    $map_options = IP_GEOLOC_RECENT_VISITORS_MAP_OPTIONS;
  }
  $marker_directory = file_create_url(ip_geoloc_marker_directory());
  $marker_dimensions = explode('x', ip_geoloc_marker_dimensions());
  $marker_width = (int) $marker_dimensions[0];
  $marker_height = (int) $marker_dimensions[1];
  $ip_geoloc_marker_anchor_pos = $this->config
    ->get('ip_geoloc_marker_anchor_pos') ? $this->config
    ->get('ip_geoloc_marker_anchor_pos') : 'bottom';
  switch ($ip_geoloc_marker_anchor_pos) {
    case 'top':
      $marker_anchor = 0;
      break;
    case 'middle':
      $marker_anchor = (int) (($marker_height + 1) / 2);
      break;
    default:
      $marker_anchor = $marker_height;
  }
  ip_geoloc_debug(t('IPGV&M: passing the following to Google Maps:'));
  ip_geoloc_debug(t('- map options %options:', [
    '%options' => $map_options,
  ]));
  ip_geoloc_debug(t('- center option: @option', [
    '@option' => $center_option,
  ]));
  ip_geoloc_debug(t('- visitor marker: %marker', [
    '%marker' => $visitor_marker,
  ]));
  ip_geoloc_debug(t('- use GPS: @gps', [
    '@gps' => (bool) $visitor_location_gps,
  ]));
  ip_geoloc_debug(t('- visitor location fallback: (@lat, @lng)', [
    '@lat' => empty($center_latlng[0]) ? '-' : $center_latlng[0],
    '@lng' => empty($center_latlng[1]) ? '-' : $center_latlng[1],
  ]));
  ip_geoloc_debug(t('- marker directory : %dir', [
    '%dir' => $marker_directory,
  ]));
  ip_geoloc_debug(t('- marker dimensions : w@w x h@h px, anchor: @a px', [
    '@w' => $marker_width,
    '@h' => $marker_height,
    '@a' => $marker_anchor,
  ]));
  ip_geoloc_debug(t('- @count locations found', [
    '@count' => count($locations),
  ]));

  // Locations transferred to JS via the settings array aren't refreshed in
  // AJAX contexts. That's why we are doing it this messy way. @todo: refactor.

  //@TODO  Review how to migrate this
  $output = "\n<script>\nif (typeof(ip_geoloc_locations) === 'undefined') {\n ip_geoloc_locations = new Array();\n}\n";
  $output .= "ip_geoloc_locations['{$div_id}'] = [\n";
  $illegal_chars = [
    "\n",
    "\r",
  ];
  foreach ($locations as $location) {
    if (isset($location->type) && $location->type != 'point') {
      continue;
    }

    // Balloon text must not have newlines, use <br/> instead.
    $balloon_text = NULL;
    if (!empty($location->balloon_text)) {
      $balloon_text = str_replace($illegal_chars, ' ', $location->balloon_text);
      $balloon_text = addslashes($balloon_text);
    }
    $output .= '{"type":"point"' . (empty($location->marker_color) ? '' : ',"marker_color":"' . $location->marker_color . '"') . (empty($balloon_text) ? '' : ',"balloon_text":"' . $balloon_text . '"') . (empty($location->open) ? '' : ',"open":1') . ',"latitude":' . $location->latitude . ',"longitude":' . $location->longitude . "},\n";
    $color = empty($location->marker_color) ? t('default') . " [{$marker_color}]" : $location->marker_color;
    $coords = isset($location->latitude) ? $location->latitude . ', ' . $location->longitude : '';
    $msg = '- ' . t('marker') . " {$color} ({$coords})<br/>{$balloon_text}<br/>";
    ip_geoloc_debug($msg);
  }
  $output .= "];\n</script>\n";
  $settings = [
    'ip_geoloc_multi_location_map_div' => $div_id,
    'ip_geoloc_multi_location_map_options' => Json::decode($map_options),
    'ip_geoloc_multi_location_center_option' => (int) $center_option,
    'ip_geoloc_multi_location_center_latlng' => $center_latlng,
    'ip_geoloc_multi_location_visitor_marker' => $visitor_marker,
    'ip_geoloc_multi_location_visitor_location_gps' => $visitor_location_gps,
    'ip_geoloc_multi_location_marker_directory' => $marker_directory,
    'ip_geoloc_multi_location_marker_width' => (int) $marker_width,
    'ip_geoloc_multi_location_marker_height' => (int) $marker_height,
    'ip_geoloc_multi_location_marker_anchor' => (int) $marker_anchor,
    'ip_geoloc_multi_location_marker_default_color' => $marker_color,
    'ip_geoloc_locations' => $locations,
  ];
  if (!isset($map_style)) {
    $map_style = IP_GEOLOC_MAP_DIV_DEFAULT_STYLE;
  }
  $map_placeholder = "<div id='{$div_id}'" . (empty($map_style) ? '' : " style='{$map_style}'") . '></div>';
  $items_array = [
    '#theme' => 'ip_geoloc_map',
    '#ip_geoloc_output_map_multi_location' => [
      '#markup' => Markup::create($map_placeholder),
    ],
  ];
  $items_array['#attached']['html_head'][] = [
    [
      '#type' => 'html_tag',
      '#tag' => 'script',
      '#value' => $output,
    ],
  ];
  $items_array['#attached']['library'][] = 'ip_geoloc/multi_location_js_style_map';
  $items_array['#attached']['drupalSettings'] = $settings;
  return \Drupal::service('renderer')
    ->render($items_array);
}