View source
<?php
require_once 'ip_geoloc_plugin_style.inc';
define('LEAFLET_MARKERCLUSTER_EXCLUDE_FROM_CLUSTER', 1);
define('LEAFLET_SYNC_CONTENT_TO_MARKER', 1 << 1);
define('LEAFLET_SYNC_MARKER_TO_CONTENT', 1 << 2);
define('LEAFLET_SYNC_MARKER_TO_CONTENT_WITH_POPUP', 1 << 3);
define('LEAFLET_SYNC_REVERT_LAST_MARKER_ON_MAP_OUT', 1 << 4);
define('TWEENMAX_VERSION', '2.1.3');
class ip_geoloc_plugin_style_leaflet extends views_plugin_style {
public function option_definition() {
$options = parent::option_definition();
$options['map'] = array(
'default' => 'OSM Mapnik',
);
$options['map_height'] = array(
'default' => 300,
);
$latitude = module_exists('location') ? 'location_latitude' : 'ip_geoloc_latitude';
$longitude = module_exists('location') ? 'location_longitude' : ($latitude == 'ip_geoloc_latitude' ? 'ip_geoloc_longitude' : $latitude);
$options['ip_geoloc_views_plugin_latitude'] = array(
'default' => $latitude,
);
$options['ip_geoloc_views_plugin_longitude'] = array(
'default' => $longitude,
);
$options['default_marker'] = array(
'contains' => array(
'default_marker_color' => array(
'default' => '',
),
'default_marker_special_char' => array(
'default' => '',
),
'default_marker_special_char_class' => array(
'default' => '',
),
),
);
$options['visitor_marker'] = array(
'contains' => array(
'visitor_marker_color' => array(
'default' => '',
),
'visitor_marker_special_char' => array(
'default' => '',
),
'visitor_marker_special_char_class' => array(
'default' => '',
),
'visitor_marker_balloon_text' => array(
'default' => '',
),
'visitor_marker_accuracy_circle' => array(
'default' => FALSE,
),
),
);
$options['differentiator'] = array(
'contains' => array(
'differentiator_field' => array(
'default' => '',
),
),
);
$options['center_option'] = array(
'default' => 0,
);
$options['tags'] = array(
'contains' => array(
'marker_tag' => array(
'default' => '',
),
'tag_css_class' => array(
'default' => 'tag-inside-marker',
),
),
);
$options['tooltips'] = array(
'contains' => array(
'marker_tooltip' => array(
'default' => '',
),
),
);
$options['class_names'] = array(
'contains' => array(
'marker_class_names' => array(
'default' => array(),
),
),
);
$options['sync'] = array(
'contains' => array(
LEAFLET_SYNC_CONTENT_TO_MARKER => array(
'default' => FALSE,
),
LEAFLET_SYNC_MARKER_TO_CONTENT => array(
'default' => FALSE,
),
LEAFLET_SYNC_MARKER_TO_CONTENT_WITH_POPUP => array(
'default' => TRUE,
),
LEAFLET_SYNC_REVERT_LAST_MARKER_ON_MAP_OUT => array(
'default' => TRUE,
),
),
);
$options['full_screen'] = array(
'default' => FALSE,
);
$options['scale_metric'] = array(
'default' => FALSE,
);
$options['scale_imperial'] = array(
'default' => FALSE,
);
$options['zoom_indicator'] = array(
'default' => FALSE,
);
$options['on_click_options'] = array(
'contains' => array(
'goto_content_on_click' => array(
'default' => FALSE,
),
'open_balloons_on_click' => array(
'default' => TRUE,
),
),
);
$options['on_hover_options'] = array(
'contains' => array(
'open_balloons_on_hover' => array(
'default' => FALSE,
),
'polygon_add_shadow_on_hover' => array(
'default' => FALSE,
),
'shadow_on_hover_effect' => array(
'default' => 'animated blur',
),
'use_tweenmax_for_shadow_on_hover' => array(
'default' => TWEENMAX_VERSION,
),
'polygon_fill_opacity_on_hover' => array(
'default' => '0.6',
),
'polygon_line_weight_on_hover' => array(
'default' => '',
),
),
);
$options['map_reset'] = array(
'default' => FALSE,
);
$options['map_reset_css_class'] = array(
'default' => 'R',
);
$options['map_cluster_toggle'] = array(
'default' => FALSE,
);
$options['mini_map'] = array(
'contains' => array(
'on' => array(
'default' => FALSE,
),
'height' => array(
'default' => 100,
),
'width' => array(
'default' => 150,
),
'toggle' => array(
'default' => TRUE,
),
'scope_color' => array(
'default' => 'red',
),
'zoom_delta' => array(
'default' => -5,
),
),
);
$options['cluster_radius'] = array(
'default' => module_exists('leaflet_markercluster') ? 80 : '',
);
$options['disable_clustering_at_zoom'] = array(
'default' => '',
);
$options['cluster_differentiator'] = array(
'contains' => array(
'cluster_differentiator_fields' => array(
'default' => '',
),
'zoom_ranges' => array(
'default' => array(),
),
'cluster_tooltips' => array(
'default' => TRUE,
),
'cluster_outline' => array(
'default' => 0,
),
'cluster_touch_mode' => array(
'default' => 1,
),
),
);
$options['cluster_aggregation'] = array(
'contains' => array(
'aggregation_field' => array(
'default' => '',
),
'aggregation_function' => array(
'default' => '',
),
'ranges' => array(
'contains' => array(),
),
'precision' => array(
'default' => '',
),
),
);
$range = 10;
foreach (array(
'small',
'medium',
'large',
) as $size) {
$options['cluster_aggregation']['contains']['ranges']['contains'][$size] = array(
'default' => $range,
);
$range *= 10;
}
$options['disable_clustering_at_zoom'] = array(
'default' => '',
);
$options['empty_map_center'] = array(
'default' => '',
);
$options['map_options'] = array(
'contains' => array(
'maxzoom' => array(
'default' => 18,
),
'zoom' => array(
'default' => 2,
),
'zoom_on_click' => array(
'default' => '',
),
'center_lat' => array(
'default' => '',
),
'center_lon' => array(
'default' => '',
),
'scrollwheelzoom' => array(
'default' => TRUE,
),
'dragging' => array(
'default' => TRUE,
),
'separator' => array(
'default' => '<br/>',
),
),
);
$options['vector_display']['contains'] = array(
'stroke_override' => array(
'default' => 0,
),
'stroke' => array(
'default' => 1,
),
'color' => array(
'default' => '',
),
'weight' => array(
'default' => '',
),
'opacity' => array(
'default' => '',
),
'dashArray' => array(
'default' => '',
),
'fill' => array(
'default' => 1,
),
'fillColor' => array(
'default' => '',
),
'fillOpacity' => array(
'default' => '',
),
'clickable' => array(
'default' => 1,
),
);
return $options;
}
public function options_form(&$form, &$form_state) {
parent::options_form($form, $form_state);
$path = drupal_get_path('module', 'ip_geoloc');
$select_css_file = strpos(ip_geoloc_marker_directory(), 'amarkers') ? 'ip_geoloc_admin_select_amarkers.css' : 'ip_geoloc_admin_select_markers.css';
$form['#attached'] = array(
'css' => array(
"{$path}/css/ip_geoloc_admin.css",
"{$path}/css/{$select_css_file}",
),
);
$form_state['renderer'] = 'leaflet';
$weight = 1;
$this
->_add_map_and_height($form, $weight);
ip_geoloc_plugin_style_bulk_of_form($this, $weight, $form, $form_state);
$form['center_option']['#options'][0] = t('Auto-box to fit all markers (include visitor marker if color <strong>not</strong> set to <none>)');
$lib_markercluster = module_exists('leaflet_markercluster') ? leaflet_markercluster_get_library_path() : FALSE;
$fields = ip_geoloc_get_display_fields($this->display->handler, FALSE, TRUE);
$this
->_add_default_marker($form, $weight);
$this
->_add_visitor_marker($form, $weight);
$this
->_add_check_boxes($form, $lib_markercluster, $weight);
$this
->_add_mini_map_inset($form, $weight);
$this
->_add_marker_tags($form, $fields, $weight);
$this
->_add_marker_tooltips($form, $fields, $weight);
$this
->_add_marker_class_names($form, $fields, $weight);
$this
->_add_sync($form, $weight);
$this
->_add_markercluster($form, $lib_markercluster, $weight);
$this
->_add_cluster_differentiator($form, $form_state, $lib_markercluster, $weight);
$this
->_add_more_map_options($form, $weight);
$this
->_add_vector_display_options($form, $weight);
}
private function _add_map_and_height(&$form, &$weight) {
$maps = array();
foreach (ip_geoloc_plugin_style_leaflet_map_get_info() as $key => $map) {
$maps[$key] = $map['label'];
}
$form['map'] = array(
'#title' => t('Map'),
'#type' => 'select',
'#options' => $maps,
'#default_value' => $this->options['map'],
'#required' => TRUE,
'#weight' => $weight++,
);
$desc1 = t('Examples: <em>250</em> or <em>50em</em> or <em>40vh</em> (percentage of viewport height).');
$desc2 = t('If left blank, the height defaults to 300 pixels. The width of the map will extend to its bounding container.');
$desc3 = t('You may enter <em><none></em>. If you do, then the height attribute must be set through Javascript or CSS elsewhere or the map will not display. CSS example: <em>.ip-geoloc-map .leaflet-container { height: 150px; }</em>');
$form['map_height'] = array(
'#title' => t('Map height'),
'#type' => 'textfield',
'#size' => 7,
'#default_value' => $this->options['map_height'],
'#description' => $desc1 . '<br/>' . $desc2 . '<br/>' . $desc3,
'#weight' => $weight++,
);
}
private function _add_default_marker(&$form, &$weight) {
$path = drupal_get_path('module', 'ip_geoloc');
$desc1 = t('In addition to selecting a color, you may superimpose a special icon on top of each marker. <br><a target="fsymbols" href="!url_fsymbols">fsymbols</a> characters can be copied and pasted straight into the <strong>Font icon character</strong> field. Other libraries like <a target="fontawesome" href="!url_fontawesome">Font Awesome</a> and <a target="flaticon" href="!url_flaticon">flaticon</a> use names that you type in the <strong>Font icon class</strong> field.', array(
'!url_fsymbols' => url('http://fsymbols.com'),
'!url_fontawesome' => url('http://fortawesome.github.io/Font-Awesome/cheatsheet'),
'!url_flaticon' => url('http://flaticon.com'),
));
$desc2 = t('<em>fsymbols</em> require no further installation. For other libraries see the <a target="readme" href="!url_readme">README</a>.', array(
'!url_readme' => url("{$path}/README.txt"),
));
$desc3 = t('All this works best with the markers from the <em>/amarkers</em> directory, configurable <a target="config" href="!url_config">here</a>.', array(
'!url_config' => url('admin/config/system/ip_geoloc'),
));
$form['default_marker'] = array(
'#type' => 'fieldset',
'#title' => t('Default marker style'),
'#description' => $desc1 . '<br/>' . $desc2 . '<br/>' . $desc3,
'#weight' => $weight++,
);
$form['default_marker']['default_marker_color'] = array(
'#title' => t('Style/color'),
'#type' => 'select',
'#default_value' => $this->options['default_marker']['default_marker_color'],
'#options' => ip_geoloc_marker_colors(),
'#description' => t('Select an image to use for all location markers whose images are not overridden by the <strong>Location differentiator</strong> below.'),
'#attributes' => array(
'class' => array(
'marker-color',
),
),
);
$form['default_marker']['default_marker_special_char'] = array(
'#title' => t('Font icon character'),
'#type' => 'textfield',
'#size' => 8,
'#default_value' => $this->options['default_marker']['default_marker_special_char'],
'#description' => t('Paste directly from <a target="fsymbols" href="!url_fsymbols">fsymbols</a>. If the character displays in color or as a square then it may not save or display correctly.', array(
'!url_fsymbols' => url('http://text-symbols.com'),
)),
);
$desc4 = t('Use the class name from the font icon library you are using. Append <strong>light</strong>, <strong>dark</strong> or <strong>red</strong> to change the color. Examples:<br/>Font Awesome: <strong>fa fa-beer light</strong><br/>flaticon: <strong>flaticon-bicycle12 red</strong>');
$form['default_marker']['default_marker_special_char_class'] = array(
'#title' => t('Font icon class'),
'#type' => 'textfield',
'#size' => 25,
'#default_value' => $this->options['default_marker']['default_marker_special_char_class'],
'#description' => $desc4,
);
}
private function _add_visitor_marker(&$form, &$weight) {
$form['visitor_marker'] = array(
'#type' => 'fieldset',
'#title' => t('Visitor marker style'),
'#description' => t('For the visitor marker to show, enable the <em>Set my location</em> block and/or tick the option to periodically reverse-geocode via Google, under the <a href="@config_page">Data collection options</a>.', array(
'@config_page' => url('admin/config/system/ip_geoloc'),
)),
'#weight' => $weight++,
);
$visitor_marker_colors = array(
'none' => '<' . t('none') . '>',
) + ip_geoloc_marker_colors();
unset($visitor_marker_colors['0']);
$form['visitor_marker']['visitor_marker_color'] = array(
'#title' => t('Style/color'),
'#type' => 'select',
'#multiple' => FALSE,
'#default_value' => $this->options['visitor_marker']['visitor_marker_color'],
'#options' => $visitor_marker_colors,
'#attributes' => array(
'class' => array(
'marker-color',
),
),
);
$form['visitor_marker']['visitor_marker_special_char'] = array(
'#title' => t('Font icon character'),
'#type' => 'textfield',
'#size' => 8,
'#default_value' => $this->options['visitor_marker']['visitor_marker_special_char'],
'#description' => t('As above'),
);
$form['visitor_marker']['visitor_marker_special_char_class'] = array(
'#title' => t('Font icon class'),
'#type' => 'textfield',
'#size' => 25,
'#default_value' => $this->options['visitor_marker']['visitor_marker_special_char_class'],
'#description' => t('As above.'),
);
$form['visitor_marker']['visitor_marker_balloon_text'] = array(
'#title' => t('Visitor balloon text'),
'#type' => 'textarea',
'#rows' => 3,
'#default_value' => $this->options['visitor_marker']['visitor_marker_balloon_text'],
'#description' => t("You may use safe HTML and tokens. The special token <em>[visitor-location:surrounding-polygon]</em> returns the title of the node that contains a Geofield polygon that surrounds the visitor's location."),
);
$form['visitor_marker']['token_browser'] = array(
'#type' => 'markup',
'#theme' => 'token_tree_link',
'#token_types' => array(
'visitor-location',
),
'#prefix' => '<div>',
'#suffix' => '</div>',
);
$form['visitor_marker']['visitor_marker_accuracy_circle'] = array(
'#title' => t('Accuracy circle'),
'#type' => 'checkbox',
'#default_value' => $this->options['visitor_marker']['visitor_marker_accuracy_circle'],
'#description' => t("Display a circle depicting where the visitor's real location is most likely to be."),
);
}
private function _add_marker_tags(&$form, $fields, &$weight) {
$form['tags'] = array(
'#title' => t('Marker tags'),
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => empty($this->options['tags']['marker_tag']),
'#description' => t('Each marker may have a tag. A tag is a number or short text shown permanently above, below or inside the marker.'),
'#weight' => $weight++,
);
$form['tags']['marker_tag'] = array(
'#title' => t('Views field to populate tags'),
'#type' => 'select',
'#default_value' => $this->options['tags']['marker_tag'],
'#options' => $fields,
'#description' => t('Example: "Content: Title". Use "Global: View result counter" if you want to number your locations.'),
);
$form['tags']['tag_css_class'] = array(
'#title' => t('Tag position and style'),
'#type' => 'textfield',
'#default_value' => $this->options['tags']['tag_css_class'],
'#description' => t('The CSS class or classes applied to each tag. Tagged marker CSS classes coming with this module are <strong>tag-above-marker</strong>, <strong>tag-below-marker</strong> and <strong>tag-inside-marker</strong>. If you opted to have <em>no markers</em>, i.e. tags only, you may use <strong>tag-rounded-corners</strong> or <strong>tag-pointy-circle</strong>, which is recommended for numbers. You may also create your own CSS classes and use them here.'),
);
}
private function _add_marker_tooltips(&$form, $fields, &$weight) {
$form['tooltips'] = array(
'#title' => t('Marker tooltips'),
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => empty($this->options['tooltips']['marker_tooltip']),
'#description' => t('In addition to balloons, which pop up when markers are <em>clicked</em>, you can have tooltips. A tooltip is a short text that appears when you <em>hover</em> over a marker.'),
'#weight' => $weight++,
);
$note_polygons = t('Applies to markers. If you want tooltips for lines and polygons too, please use this selector in combination with <a href="@url_leaflet_label">Leaflet Label</a>.', array(
'@url_leaflet_label' => url('http://drupal.org/project/leaflet_label'),
));
$form['tooltips']['marker_tooltip'] = array(
'#title' => t('Views field to populate tooltips'),
'#type' => 'select',
'#default_value' => $this->options['tooltips']['marker_tooltip'],
'#options' => $fields,
'#description' => t('Example: "Content: Title"') . '<br/>' . $note_polygons,
);
}
private function _add_marker_class_names(&$form, $fields, &$weight) {
$form['class_names'] = array(
'#title' => t('Marker class names (advanced)'),
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => empty($this->options['class_names']['marker_class_names']),
'#description' => t('Select fields whose values will be appended to the <em>class</em> attribute on the marker HTML.'),
'#weight' => $weight++,
);
$note1 = t('NOTE: This option will only have an effect when you also have CCS or Javascript code that responds to the added classes.');
$note2 = t('The class name format is <em>field-[machine-name]__[value]</em>. Spaces and underscores in field name and value are converted to hyphens. If the value is a list option, the machine-name is used. To check inspect the page source in your browser. Example <em>field-size_extra-large</em>');
$form['class_names']['marker_class_names'] = array(
'#title' => t('Views fields whose values will be added as class names'),
'#type' => 'select',
'#multiple' => TRUE,
'#size' => 6,
'#default_value' => $this->options['class_names']['marker_class_names'],
'#options' => $fields,
'#description' => "{$note1} {$note2}",
);
}
private function _add_check_boxes(&$form, $lib_markercluster, &$weight) {
$form['full_screen'] = array(
'#title' => t('Add a full-screen toggle to the map'),
'#type' => 'checkbox',
'#default_value' => $this->options['full_screen'],
'#weight' => $weight++,
);
$lib_fullscreen = libraries_get_path('leaflet-fullscreen');
if ($lib_fullscreen) {
$file_fullscreen = $lib_fullscreen . '/dist/Leaflet.fullscreen.min.js';
if (!file_exists($file_fullscreen)) {
$form['full_screen']['#description'] = t('Error: <em>leaflet-fullscreen</em> library found, but %js_file is missing.', array(
'%js_file' => $file_fullscreen,
));
}
}
else {
$form['full_screen']['#description'] = t('Requires this <a target="_js" href="@js_lib">JS library</a> to be downloaded to <em>/sites/all/libraries</em>. Change the directory name to <em>leaflet-fullscreen</em>.', array(
'@js_lib' => 'https://github.com/Leaflet/Leaflet.fullscreen',
));
}
$form['scale_imperial'] = array(
'#title' => t('Add an imperial (miles) scale'),
'#type' => 'checkbox',
'#default_value' => $this->options['scale_imperial'],
'#weight' => $weight++,
);
$form['scale_metric'] = array(
'#title' => t('Add a metric (km) scale'),
'#type' => 'checkbox',
'#default_value' => $this->options['scale_metric'],
'#weight' => $weight++,
);
$form['zoom_indicator'] = array(
'#title' => t('Add an indicator showing the active zoom level'),
'#type' => 'checkbox',
'#default_value' => $this->options['zoom_indicator'],
'#weight' => $weight++,
);
$form['map_reset'] = array(
'#title' => t('Add a reset button'),
'#type' => 'checkbox',
'#default_value' => $this->options['map_reset'],
'#description' => t('This button allows the visitor to reset the map to its initial bounds (center and zoom level).'),
'#weight' => $weight++,
);
$form['map_reset_css_class'] = array(
'#title' => t('CSS class to apply to reset button'),
'#type' => 'textfield',
'#size' => 40,
'#default_value' => $this->options['map_reset_css_class'],
'#description' => t('You can use this to superimpose a font-icon on the button. For instance, if you have the Font Awesome library loaded for your markers, try <strong>fa fa-repeat</strong>. If you enter only one or two characters, for example <strong>R</strong>, these will be used verbatim as the label instead.'),
'#weight' => $weight++,
'#states' => array(
'visible' => array(
'input[name="style_options[map_reset]"]' => array(
'checked' => TRUE,
),
),
),
);
$form['map_cluster_toggle'] = array(
'#title' => t('Add cluster toggle button'),
'#type' => 'checkbox',
'#default_value' => $this->options['map_cluster_toggle'],
'#description' => t('This button allows the visitor to toggle marker clustering on/off at any time and at any zoom level.') . '<br/>' . t('A cluster radius must be specified below.'),
'#weight' => $weight++,
);
$form['on_click_options'] = array(
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#title' => t('Behaviour when clicked'),
'#description' => t('These apply to markers, polygons and polylines.'),
'#weight' => $weight++,
);
$form['on_click_options']['goto_content_on_click'] = array(
'#title' => t('When <em>clicked</em>, go to the associated content page'),
'#type' => 'checkbox',
'#default_value' => $this->options['on_click_options']['goto_content_on_click'],
);
$form['on_click_options']['open_balloons_on_click'] = array(
'#title' => t('When <em>clicked</em>, pop up a balloon showing non-excluded fields'),
'#type' => 'checkbox',
'#default_value' => $this->options['on_click_options']['open_balloons_on_click'],
);
$form['on_hover_options'] = array(
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#title' => t('Behaviour when hovered'),
'#weight' => $weight++,
);
$form['on_hover_options']['open_balloons_on_hover'] = array(
'#title' => t('When <em>hovered</em>, pop up a balloon showing non-excluded fields'),
'#description' => t('Applies to markers, polygons and polylines.'),
'#type' => 'checkbox',
'#default_value' => $this->options['on_hover_options']['open_balloons_on_hover'],
);
$form['on_hover_options']['polygon_add_shadow_on_hover'] = array(
'#title' => t('When <em>hovered</em>, add an effect to highlight the hovered element'),
'#description' => t('Applies to polygons. Does not apply to markers.'),
'#type' => 'checkbox',
'#default_value' => $this->options['on_hover_options']['polygon_add_shadow_on_hover'],
);
$form['on_hover_options']['shadow_on_hover_effect'] = array(
'#title' => t('Choose hover effect'),
'#description' => t('The SURGE effect was designed by Matt Winans for <a href="!url">the SURGE movement</a>.', array(
'!url' => url('http://surgemovement.com/map'),
)),
'#type' => 'radios',
'#options' => array(
'animated blur' => t('Blur/shadow, animated'),
'surge' => t('SURGE effect, animated'),
),
'#default_value' => $this->options['on_hover_options']['shadow_on_hover_effect'],
'#states' => array(
'invisible' => array(
':input[name="style_options[on_hover_options][polygon_add_shadow_on_hover]"]' => array(
'checked' => FALSE,
),
),
),
);
$form['on_hover_options']['use_tweenmax_for_shadow_on_hover'] = array(
'#title' => t('Version of <em>TweenMax</em> to use for generating animated hover effects.'),
'#description' => t('You may opt for the <em>TweenMax</em> library to generate anamated drop shadows.') . '<br/>' . t('<a href="!url" target="_tween">TweenMax</a> offers higher performance and wider cross-browser support, but does add 0.12MB to your map page download size.', array(
'!url' => url('https://greensock.com/tweenmax'),
)) . '<br/>' . t("If entered the minimised version of the TweenMax library will be included automatically from the CDN closest to the visitor.") . '<br/>' . t("The default version is %version. Leave blank to use pure HTML for animations instead.", array(
'%version' => TWEENMAX_VERSION,
)),
'#type' => 'textfield',
'#size' => 6,
'#default_value' => $this->options['on_hover_options']['use_tweenmax_for_shadow_on_hover'],
'#states' => array(
'invisible' => array(
':input[name="style_options[on_hover_options][polygon_add_shadow_on_hover]"]' => array(
'checked' => FALSE,
),
),
),
);
$form['on_hover_options']['polygon_fill_opacity_on_hover'] = array(
'#title' => t('For polygons: when <em>hovered</em> change <em>fill opacity</em> to'),
'#description' => t('A fraction between 0 (transparent) and 1 (solid). Leave blank for no change.'),
'#type' => 'textfield',
'#size' => 4,
'#default_value' => $this->options['on_hover_options']['polygon_fill_opacity_on_hover'],
);
$form['on_hover_options']['polygon_line_weight_on_hover'] = array(
'#title' => t('For polygons: when <em>hovered</em> change <em>line weight</em> to'),
'#description' => t('Width in pixels, typically 1..10. Use 0 to remove outline altogether. Leave blank for no change.') . '<br/>' . t('Line color, line opacity and line dash pattern remain unchanged from what you specified in the section <em>Options for Polygons, Polylines and Circles</em>, below.'),
'#type' => 'textfield',
'#size' => 4,
'#default_value' => $this->options['on_hover_options']['polygon_line_weight_on_hover'],
);
$form['on_hover_options']['tip'] = array(
'#type' => 'markup',
'#markup' => t('TIP: You can animate the transition of <em>fill opacity</em> and <em>line weight</em> by adding a CCS rule like this to your theme: <br/> <code>path.leaflet-interactive { transition: all 0.7s linear }</code>'),
);
if (!$lib_markercluster) {
$form['map_cluster_toggle']['#description'] .= '<br/>' . t('<a href="!url_project">Leaflet MarkerCluster</a> must be enabled.', array(
'!url_project' => url('http://drupal.org/project/leaflet_markercluster'),
));
}
}
private function _add_sync(&$form, &$weight) {
$form['sync'] = array(
'#title' => t('Cross-highlighting between map markers and page content outside the map'),
'#description' => '<br/>' . t('For the cross-highlighting to work, content outside the map must have the CSS class <em>.sync-id-[nid]</em>, where <em>[nid]</em> represents the content ID.') . ' ' . t('For Views content, you can do this by adding a <strong>Row class</strong> to the Grid, Table, HTML or Unformatted list formats of your Views Attachment or Block displays.'),
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => empty($this->options['sync'][LEAFLET_SYNC_CONTENT_TO_MARKER]),
'#weight' => $weight++,
);
$note = t('You can redefine this class to change the default look.');
$form['sync'][LEAFLET_SYNC_CONTENT_TO_MARKER] = array(
'#title' => t('When hovering markers on the map, highlight associated content on the page'),
'#type' => 'checkbox',
'#default_value' => $this->options['sync'][LEAFLET_SYNC_CONTENT_TO_MARKER] && $this->options['sync'][LEAFLET_SYNC_MARKER_TO_CONTENT],
'#description' => t('Content is highlighted dynamically through the automatic addition of the CSS class <em>.synced-marker-hover</em>.') . ' ' . $note,
'#weight' => $weight++,
);
$caveat = t('For this feature to work in combination with any <em>sorting</em> on the hovered content, the associated Views display must have <em>Use Ajax: No</em>.');
$form['sync'][LEAFLET_SYNC_MARKER_TO_CONTENT] = array(
'#title' => t('When hovering content, highlight associated markers on the map'),
'#type' => 'checkbox',
'#default_value' => $this->options['sync'][LEAFLET_SYNC_MARKER_TO_CONTENT],
'#description' => t('Markers are highlighted dynamically through the automatic addition of the CSS class <em>.synced-content-hover</em>.') . ' ' . $note . '<br/>' . $caveat,
'#weight' => $weight++,
);
$form['sync'][LEAFLET_SYNC_MARKER_TO_CONTENT_WITH_POPUP] = array(
'#title' => t('As above, but also pop up marker balloons'),
'#type' => 'checkbox',
'#default_value' => $this->options['sync'][LEAFLET_SYNC_MARKER_TO_CONTENT_WITH_POPUP],
'#states' => array(
'visible' => array(
':input[name="style_options[sync][4]"]' => array(
'checked' => TRUE,
),
),
),
'#weight' => $weight++,
);
$form['sync'][LEAFLET_SYNC_REVERT_LAST_MARKER_ON_MAP_OUT] = array(
'#title' => t('Unhighlight marker and close its balloon when hovering off the map'),
'#type' => 'checkbox',
'#default_value' => $this->options['sync'][LEAFLET_SYNC_REVERT_LAST_MARKER_ON_MAP_OUT],
'#states' => array(
'visible' => array(
':input[name="style_options[sync][4]"]' => array(
'checked' => TRUE,
),
),
),
'#weight' => $weight++,
);
}
private function _add_mini_map_inset(&$form, &$weight) {
$form['mini_map'] = array(
'#title' => t('Mini-map inset'),
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#description' => t('A zoomed-out version of the main map as a mini-map inset in the bottom corner.'),
'#weight' => $weight++,
);
$form['mini_map']['on'] = array(
'#title' => t('Enable mini-map inset'),
'#type' => 'checkbox',
'#default_value' => !empty($this->options['mini_map']['on']),
);
$form['mini_map']['height'] = array(
'#title' => t('Height of inset'),
'#type' => 'textfield',
'#size' => 4,
'#field_suffix' => t('px'),
'#default_value' => $this->options['mini_map']['height'],
'#states' => array(
'visible' => array(
'input[name="style_options[mini_map][on]"]' => array(
'checked' => TRUE,
),
),
),
);
$form['mini_map']['width'] = array(
'#title' => t('Width of inset'),
'#type' => 'textfield',
'#size' => 4,
'#field_suffix' => t('px'),
'#default_value' => $this->options['mini_map']['width'],
'#states' => array(
'visible' => array(
'input[name="style_options[mini_map][on]"]' => array(
'checked' => TRUE,
),
),
),
);
$form['mini_map']['toggle'] = array(
'#title' => t('Allow visitor to minimise inset'),
'#type' => 'checkbox',
'#default_value' => !empty($this->options['mini_map']['toggle']),
'#states' => array(
'visible' => array(
'input[name="style_options[mini_map][on]"]' => array(
'checked' => TRUE,
),
),
),
);
$form['mini_map']['scope_color'] = array(
'#title' => t('Scope rectangle color'),
'#type' => 'textfield',
'#size' => 10,
'#default_value' => $this->options['mini_map']['scope_color'],
'#description' => t('<em>#rrggbb</em> or <a target="_colors" href="@url">color name</a>.', array(
'@url' => url('http://www.w3schools.com/html/html_colornames.asp'),
)),
'#states' => array(
'visible' => array(
'input[name="style_options[mini_map][on]"]' => array(
'checked' => TRUE,
),
),
),
);
$form['mini_map']['zoom_delta'] = array(
'#title' => t('Zoom delta'),
'#type' => 'textfield',
'#size' => 3,
'#default_value' => $this->options['mini_map']['zoom_delta'],
'#description' => t('The difference between the zoom levels of main map and mini-map.'),
'#states' => array(
'visible' => array(
'input[name="style_options[mini_map][on]"]' => array(
'checked' => TRUE,
),
),
),
);
$lib_minimap = libraries_get_path('leaflet-minimap');
if ($lib_minimap) {
$file_minimap = $lib_minimap . '/dist/Control.MiniMap.min.js';
if (!file_exists($file_minimap)) {
$form['mini_map']['#description'] .= '<br/>' . t('Error: <em>leaflet-minimap</em> library found, but %js_file is missing.', array(
'%js_file' => $file_minimap,
));
}
}
else {
$form['mini_map']['#description'] .= '<br/>' . t('Requires this <a target="_js" href="@js_lib">JS library</a> to be downloaded to <em>/sites/all/libraries</em>. Change the directory name to <em>leaflet-minimap</em>.', array(
'@js_lib' => 'https://github.com/Norkart/Leaflet-Minimap',
));
}
}
private function _add_markercluster(&$form, $lib_markercluster, &$weight) {
$desc_a = t('A typical cluster radius is 20 to 100 px. When you use a <em>cluster region differentiator</em> (see below), a marker radius of 200 px or more may give superior results. <br/>The visitor marker is excluded from clustering. Enter 0 to disable clustering altogether.');
$desc_b = t('Requires the <a target="project" href="!url_project">Leaflet MarkerCluster</a> module.', array(
'!url_project' => url('http://drupal.org/project/leaflet_markercluster'),
));
$form['cluster_radius'] = array(
'#title' => t('Marker cluster radius'),
'#type' => 'textfield',
'#field_suffix' => t('px'),
'#size' => 4,
'#default_value' => $this->options['cluster_radius'],
'#description' => $lib_markercluster ? $desc_a : $desc_b,
'#weight' => $weight++,
);
$form['disable_clustering_at_zoom'] = array(
'#title' => t('Disable clustering at zoom'),
'#type' => 'textfield',
'#size' => 4,
'#default_value' => is_numeric($this->options['disable_clustering_at_zoom']) ? $this->options['disable_clustering_at_zoom'] : '',
'#description' => t('If you specify a zoom level, then there will be no clustering beyond that zoom level, regardless of the radius specified.'),
'#weight' => $weight++,
);
$form['allow_clusters_of_one'] = array(
'#title' => t('Allow clusters of one'),
'#type' => 'checkbox',
'#default_value' => $this->options['allow_clusters_of_one'],
'#description' => t('Especially recommended when your clusters employ aggregation functions.'),
'#weight' => $weight++,
);
}
private function _add_cluster_differentiator(&$form, &$form_state, $lib_markercluster, &$weight) {
$path = drupal_get_path('module', 'ip_geoloc');
$intro = t('Region-aware marker clustering with <a target="regionbound" href="!url_regionbound">RegionBound</a>. See the <a target="readme" href="!url_readme">README</a> for details.', array(
'!url_regionbound' => url('http://regionbound.com'),
'!url_readme' => url("{$path}/README.txt"),
));
$form['cluster_differentiator'] = array(
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#title' => t('Cluster region differentiator'),
'#description' => '<em>' . $intro . '</em><br/>',
'#prefix' => '<div id="cluster-differentiator-wrapper">',
'#suffix' => '</div>',
'#weight' => $weight++,
);
$region_field_names = NULL;
if (isset($form_state['triggering_element'])) {
if (strpos($form_state['triggering_element']['#id'], 'cluster-differentiator-field') > 0) {
$region_field_names = $form_state['triggering_element']['#value'];
}
}
else {
$region_field_names = $this->options['cluster_differentiator']['cluster_differentiator_fields'];
}
if (!module_exists('leaflet_markercluster')) {
$desc = t('Requires the <a target="project" href="!url_project">Leaflet MarkerCluster</a> module', array(
'!url_project' => url('http://drupal.org/project/leaflet_markercluster'),
));
$form['cluster_differentiator']['#description'] .= $desc . ' ' . t('and <a href="!url_regionbound">RegionBound</a> JS plugin.', array(
'!url_regionbound' => url('http://regionbound.com'),
));
}
elseif ($lib_markercluster && (empty($region_field_names) || !reset($region_field_names))) {
$note_region = t('Download the file %js from <a target="regionbound" href="!url_regionbound">Regionbound</a> and drop it in %directory, without renaming. Then select your region differentiator below.', array(
'%js' => IP_GEOLOC_LEAFLET_MARKERCLUSTER_REGIONBOUND_JS,
'%directory' => $lib_markercluster,
'!url_regionbound' => url('http://regionbound.com'),
));
$form['cluster_differentiator']['#description'] .= "<p>{$note_region}</p>";
}
$fields = ip_geoloc_get_display_fields($this->display->handler, FALSE, FALSE);
$form['cluster_differentiator']['cluster_differentiator_fields'] = array(
'#title' => t('Region differentiator'),
'#type' => 'select',
'#multiple' => TRUE,
'#size' => 6,
'#options' => $fields,
'#default_value' => $region_field_names,
'#ajax' => array(
'callback' => '_ip_geoloc_plugin_style_leaflet_refresh_cluster_fieldset_js',
'wrapper' => 'cluster-differentiator-wrapper',
'effect' => 'fade',
'speed' => 'fast',
),
'#description' => t('Select a field (or sequence of fields) that reflect for each location marker the region hierarchy it belongs to. Examples are an <a target="drupal" href="!url_addressfield">AddressField</a>, a hierarchical taxonomy term based on regions, or individual fields for country, state, city, suburb (<em>in that order</em>). Make sure that the region differentiator you wish to use is included as a field in your view, so it appears in the list above. Note that region differentiators do <em>not</em> need to be associated with latitudes or longitudes. They are just name fields.', array(
'!url_addressfield' => url('http://drupal.org/project/addressfield'),
)),
);
$level = 0;
if (!empty($region_field_names)) {
foreach ($region_field_names as $region_field_name) {
$region_field = field_info_field($region_field_name);
$field_type = empty($region_field['type']) ? '' : $region_field['type'];
$region_depth = $this
->get_region_field_depth($region_field);
$zoom_titles = $this
->_get_zoom_titles($field_type, $fields[$region_field_name], $region_depth);
foreach ($zoom_titles as $title) {
$level++;
$default_value = isset($this->options['cluster_differentiator']['zoom_ranges'][$level]) ? $this->options['cluster_differentiator']['zoom_ranges'][$level] : '';
$form['cluster_differentiator']['zoom_ranges'][$level] = array(
'#type' => 'textfield',
'#title' => filter_xss_admin($title),
'#size' => 28,
'#default_value' => $default_value,
'#element_validate' => array(
'ip_geoloc_range_widget_validate',
),
);
}
}
if ($level > 0) {
$desc1 = $level === 1 ? t('Below enter the zoom level range to be associated with the selected differentiator.') : t('Below enter the zoom level ranges to which each of the region hierarchy levels apply.') . '<br/>' . t('Zoom ranges may start and end at any level, but must not overlap.');
$desc2 = '';
$desc3 = t('Or leave all fields blank to use the defaults and refine later.');
$zoom1 = t('Typical zoom ranges for Europe: country: 3--6, province: 7--9, city: 10--14, postcode: 15--18');
$zoom2 = t('Typical zoom ranges for US & Canada: country: 1--3, state: 4--8, city: 9--13, zip: 14--18');
$zoom3 = t('Typical zoom ranges for Australia: country: 1--2, state: 3--9, city: 10--13, suburb/postcode: 14--18');
$form['cluster_differentiator']['cluster_differentiator_fields']['#description'] = implode('<br/>', array(
"{$desc1} {$desc2}<br/>{$desc3}<br/>",
$zoom1,
$zoom2,
$zoom3,
));
}
$form['cluster_differentiator']['cluster_tooltips'] = array(
'#title' => t('Add cluster tooltips'),
'#type' => 'checkbox',
'#default_value' => $this->options['cluster_differentiator']['cluster_tooltips'],
'#description' => t("When hovering a cluster, tooltips reveal the cluster region name and the names of its populated subregions."),
);
$form['cluster_differentiator']['cluster_touch_mode'] = array(
'#title' => t('Cluster action on touch devices (e.g. mobile phones)'),
'#type' => 'radios',
'#options' => array(
1 => t('Single tap displays cluster regions, double-tap drills into cluster (default)'),
0 => t('Single tap drills into cluster. Sub-region names not displayed, but visible on mouse devices.'),
),
'#default_value' => $this->options['cluster_differentiator']['cluster_touch_mode'],
'#description' => t('Applies only to devices that do not have a mouse, like mobile phones.'),
);
$form['cluster_differentiator']['cluster_outline'] = array(
'#title' => t('Cluster population outline'),
'#type' => 'select',
'#options' => array(
0 => t('Traditional (convex hull)'),
1 => t('Avant-garde (heuristic hull)'),
),
'#default_value' => $this->options['cluster_differentiator']['cluster_outline'],
'#description' => t('When hovering a cluster, a <a target="regionbound" href="!url_regionbound">coverage outline</a> visualises the envelope or footprint of the underlying marker population. Select your preferred style of doing this.', array(
'!url_regionbound' => url('http://regionbound.com/enhanced-cluster-envelope-using-heuristic-hull'),
)),
);
}
$intro = t('Use clusters to report on region aggregates; requires <a target="regionbound" href="!url_regionbound">RegionBound</a>', array(
'!url_regionbound' => url('http://regionbound.com/coffee-prices-across-melbourne'),
));
$desc = t('This feature aggregates values of a selected field across every region and displays the resulting <em>sum/average/min/max</em> on each cluster icon at every zoom level. It also colours each cluster icon based on its aggregated value, rather than its marker count.');
$form['cluster_aggregation'] = array(
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#title' => t('Cluster aggregation'),
'#description' => "<em>{$intro}</em><p>{$desc}</p>",
'#weight' => $weight++,
);
$form['cluster_aggregation']['aggregation_field'] = array(
'#title' => t('Field to perform aggregation on'),
'#type' => 'select',
'#default_value' => $this->options['cluster_aggregation']['aggregation_field'],
'#options' => $fields,
'#description' => t('For aggregation to make sense, the selected field must be numeric or represent a list. If a list, aggregation will be applied to the element <em>count</em>.'),
);
$form['cluster_aggregation']['aggregation_function'] = array(
'#title' => t('Aggregation function'),
'#type' => 'select',
'#default_value' => $this->options['cluster_aggregation']['aggregation_function'],
'#options' => array(
'average' => t('Average'),
'maximum' => t('Maximum'),
'minimum' => t('Minimum'),
'sum' => t('Sum'),
),
);
$form['cluster_aggregation']['ranges'] = array(
'#type' => 'item',
'#description' => t('Edit the above to change the color-coding of cluster icons based on their aggregate values.'),
'#prefix' => '<div id="cluster-aggregation-aggregate">',
'#suffix' => '</div>',
);
foreach (array(
'small',
'medium',
'large',
) as $size) {
$default_value = isset($this->options['cluster_aggregation']['ranges'][$size]) ? $this->options['cluster_aggregation']['ranges'][$size] : '';
$form['cluster_aggregation']['ranges'][$size] = array(
'#title' => "{$size} " . t('goes to'),
'#type' => 'textfield',
'#size' => 8,
'#default_value' => $default_value,
);
}
$form['cluster_aggregation']['precision'] = array(
'#title' => t('Precision'),
'#type' => 'textfield',
'#size' => 2,
'#default_value' => $this->options['cluster_aggregation']['precision'],
'#description' => t('Number of significant digits used to display the aggregate value on the cluster icon. Leave blank for native formatting.'),
);
}
private function _add_more_map_options(&$form, &$weight) {
$selected_map = ip_geoloc_plugin_style_leaflet_map_get_info($this->options['map']);
$zoom_top = 21;
if (isset($selected_map['settings']['maxZoom'])) {
$zoom_top = $selected_map['settings']['maxZoom'];
}
$form['map_options'] = array(
'#title' => t('More map options'),
'#type' => 'fieldset',
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'#weight' => $weight++,
);
$form['map_options']['maxzoom'] = array(
'#title' => t('Maximum zoom level (0..@zoomtop)', array(
'@zoomtop' => $zoom_top,
)),
'#type' => 'textfield',
'#size' => 2,
'#default_value' => $this->options['map_options']['maxzoom'],
'#description' => t('Note that not all maps support all zoom levels.'),
);
$initial_zoom_max = $zoom_top;
if (is_numeric($this->options['map_options']['maxzoom'])) {
$initial_zoom_max = min($zoom_top, $this->options['map_options']['maxzoom']);
}
$form['map_options']['zoom'] = array(
'#title' => t('Initial zoom level (0..@maxzoom)', array(
'@maxzoom' => $initial_zoom_max,
)),
'#type' => 'textfield',
'#size' => 2,
'#default_value' => $this->options['map_options']['zoom'],
'#description' => t('Does not apply to auto-box centering except when only one or no markers are shown.'),
);
$form['map_options']['zoom_on_click'] = array(
'#title' => t('Zoom-on-click zoom level (1..@maxzoom)', array(
'@maxzoom' => $zoom_top,
)),
'#type' => 'textfield',
'#size' => 2,
'#default_value' => $this->options['map_options']['zoom_on_click'],
'#description' => t('Level to zoom to when a marker is clicked. Leave blank to disable this feature.'),
);
$form['map_options']['center_lat'] = array(
'#title' => t('Latitude of initial center of map'),
'#type' => 'textfield',
'#size' => 6,
'#default_value' => $this->options['map_options']['center_lat'],
'#description' => t('If both latitude and longitude are filled out, these override any centering option until the visitor changes their location.'),
);
$form['map_options']['center_lon'] = array(
'#title' => t('Longitude of initial center of map'),
'#type' => 'textfield',
'#size' => 6,
'#default_value' => $this->options['map_options']['center_lon'],
'#description' => t('If both latitude and longitude are filled out, these override any centering option until the visitor changes their location.'),
);
$form['map_options']['scrollwheelzoom'] = array(
'#title' => t('Enable scroll wheel zoom'),
'#type' => 'select',
'#default_value' => $this->options['map_options']['scrollwheelzoom'],
'#options' => array(
TRUE => t('Yes'),
FALSE => t('No'),
),
);
$form['map_options']['dragging'] = array(
'#title' => t('Dragging/Panning of the map'),
'#type' => 'select',
'#default_value' => $this->options['map_options']['dragging'],
'#options' => array(
TRUE => t('Yes'),
FALSE => t('No'),
),
);
$form['map_options']['separator'] = array(
'#title' => t('Separator used in marker balloons'),
'#type' => 'textfield',
'#size' => 10,
'#default_value' => $this->options['map_options']['separator'],
'#description' => t('You may use most HTML tags.'),
);
}
private function _add_vector_display_options(&$form, &$weight) {
$form['vector_display'] = leaflet_form_elements('vector_display', $this->options, array(
'path' => 'style_options',
));
$form['vector_display']['#title'] = t('Options for Polygons, Polylines and Circles');
$link_options = array(
'attributes' => array(
'target' => 'leaflet-manual',
),
);
$descr1 = t('These settings will overwrite these !options, that apply to Polygons, Multi-Polygons Polylines and Circles.', array(
'!options' => l(t('default Leaflet options'), 'http://leafletjs.com/reference.html#path', $link_options),
));
$descr2 = t('You may use tokens. For example, if your location content type has a color field, e.g. [node:field_color], you can use that to assign different colors to your polygons, polylines and circles.');
$form['vector_display']['#description'] = $descr1 . '<br/>' . $descr2;
$form['vector_display']['#weight'] = $weight++;
$form['vector_display']['token_browser'] = array(
'#type' => 'markup',
'#theme' => 'token_tree_link',
'#token_types' => array(
'node',
),
'#weight' => -1,
);
unset($form['vector_display']['clickable']);
}
public function options_validate(&$form, &$form_state) {
ip_geoloc_plugin_style_bulk_of_form_validate($form, $form_state);
$style_options = $form_state['values']['style_options'];
$map_height = trim($style_options['map_height']);
if (is_numeric($map_height) && $map_height <= 0) {
form_error($form['map_height'], t('Map height must be a positive number.'));
}
$selected_map = ip_geoloc_plugin_style_leaflet_map_get_info($style_options['map']);
$zoom_top = 18;
if (isset($selected_map['settings']['maxZoom'])) {
$zoom_top = $selected_map['settings']['maxZoom'];
}
$max_zoom = $style_options['map_options']['maxzoom'];
if ($max_zoom != '' && (!is_numeric($max_zoom) || $max_zoom < 0 || $max_zoom > $zoom_top)) {
form_error($form['map_options']['maxzoom'], t('"Maximum zoom level" for %map must be in range 0..@zoomtop', array(
'%map' => $selected_map['label'],
'@zoomtop' => $zoom_top,
)));
}
$zoom = $style_options['map_options']['zoom'];
if ($zoom != '' && (!is_numeric($zoom) || $zoom < 0 || $zoom > $max_zoom)) {
form_error($form['map_options']['zoom'], t('"Initial zoom level" must be a non-negative number not greater than "Maximum zoom level".'));
}
$disable_zoom = $style_options['disable_clustering_at_zoom'];
if ($disable_zoom != '' && (!is_numeric($disable_zoom) || $disable_zoom < 0 || $disable_zoom > $max_zoom)) {
form_error($form['disable_clustering_at_zoom'], t('"Disable clustering at zoom" level must be a positive number not greater than "Maximum zoom level".'));
}
if (isset($style_options['cluster_aggregation'])) {
$cluster_aggregation = $style_options['cluster_aggregation'];
if (!empty($cluster_aggregation['aggregation_field'])) {
$aggregation_field_info = field_info_field($cluster_aggregation['aggregation_field']);
$valid_types = array(
'number_integer',
'number_decimal',
'number_float',
'entityreference',
);
if (!$aggregation_field_info || !in_array($aggregation_field_info['type'], $valid_types)) {
drupal_set_message(t('A cluster aggregation field that cannot be interpreted as a number may cause unexpected errors.'));
}
}
}
}
public function render() {
if (empty($this->options['map']) || !($map = ip_geoloc_plugin_style_leaflet_map_get_info($this->options['map']))) {
return t('No Leaflet map was selected or map configuration was not found.');
}
if (!empty($this->view->live_preview)) {
return t('The preview function is incompatible with Leaflet maps so cannot be used. Please visit the page path or the block to view your map.');
}
$render_start = microtime(TRUE);
ip_geoloc_plugin_style_render_fields($this);
$goto_content_on_click = !empty($this->options['on_click_options']['goto_content_on_click']);
$open_balloons_on_click = !empty($this->options['on_click_options']['open_balloons_on_click']);
$open_balloons_on_hover = !empty($this->options['on_hover_options']['open_balloons_on_hover']);
$polygon_add_shadow_on_hover = $this->options['on_hover_options']['polygon_add_shadow_on_hover'];
$shadow_on_hover_effect = $this->options['on_hover_options']['shadow_on_hover_effect'];
$use_tweenmax_for_shadow_on_hover = trim($this->options['on_hover_options']['use_tweenmax_for_shadow_on_hover']);
$polygon_fill_opacity_on_hover = trim($this->options['on_hover_options']['polygon_fill_opacity_on_hover']);
$polygon_line_weight_on_hover = trim($this->options['on_hover_options']['polygon_line_weight_on_hover']);
$enable_balloons = $open_balloons_on_click || $open_balloons_on_hover;
$locations = ip_geoloc_plugin_style_extract_locations($this, $enable_balloons);
$this
->fill_out_location_regions($locations);
$marker_color = $this->options['default_marker']['default_marker_color'];
$visitor_marker_color = $this->options['visitor_marker']['visitor_marker_color'];
$center_option = !isset($this->options['center_option']) ? 0 : $this->options['center_option'];
$sync_flags = 0;
if (!empty($this->options['sync'][LEAFLET_SYNC_CONTENT_TO_MARKER])) {
$sync_flags |= LEAFLET_SYNC_CONTENT_TO_MARKER;
}
if (!empty($this->options['sync'][LEAFLET_SYNC_MARKER_TO_CONTENT])) {
$sync_flags |= LEAFLET_SYNC_MARKER_TO_CONTENT;
if (!empty($this->options['sync'][LEAFLET_SYNC_MARKER_TO_CONTENT_WITH_POPUP])) {
$sync_flags |= LEAFLET_SYNC_MARKER_TO_CONTENT_WITH_POPUP;
}
if (!empty($this->options['sync'][LEAFLET_SYNC_REVERT_LAST_MARKER_ON_MAP_OUT])) {
$sync_flags |= LEAFLET_SYNC_REVERT_LAST_MARKER_ON_MAP_OUT;
}
}
$has_full_screen = !empty($this->options['full_screen']);
$has_mini_map = !empty($this->options['mini_map']['on']);
$zoom_indicator = empty($this->options['zoom_indicator']) ? FALSE : TRUE;
$scale_control = FALSE;
if (!empty($this->options['scale_metric']) || !empty($this->options['scale_imperial'])) {
$scale_control = array(
'metric' => !empty($this->options['scale_metric']),
'imperial' => !empty($this->options['scale_imperial']),
);
}
$reset_control = FALSE;
if (!empty($this->options['map_reset'])) {
$label = filter_xss_admin($this->options['map_reset_css_class']);
$reset_control = array(
'label' => empty($label) ? ' ' : $label,
);
}
$cluster_control = FALSE;
if (module_exists('leaflet_markercluster') && !empty($this->options['map_cluster_toggle'])) {
$cluster_control = array(
'label' => 'C',
);
}
$cluster_radius = (int) _ip_geoloc_get_session_value('markercluster-radius');
if ($cluster_radius < 2) {
$cluster_radius = (int) $this->options['cluster_radius'];
}
$disable_clustering_at_zoom = $this->options['disable_clustering_at_zoom'];
$hull_hug_factor = empty($this->options['cluster_differentiator']['cluster_outline']) ? -1 : 'auto';
$cluster_tooltips = !empty($this->options['cluster_differentiator']['cluster_tooltips']);
$cluster_touch_mode = empty($this->options['cluster_differentiator']['cluster_touch_mode']) ? 0 : 'auto';
$cluster_aggregation_field = $this->options['cluster_aggregation']['aggregation_field'];
$cluster_aggregation_function = $this->options['cluster_aggregation']['aggregation_function'];
$cluster_aggregate_ranges = $this->options['cluster_aggregation']['ranges'];
$cluster_aggregate_precision = $this->options['cluster_aggregation']['precision'];
$allow_clusters_of_one = !empty($this->options['allow_clusters_of_one']);
$tag_css_classes = $this->options['tags']['tag_css_class'];
$marker_css_classes = $this->options['class_names']['marker_class_names'];
$module_path = drupal_get_path('module', 'ip_geoloc');
$marker_path = file_create_url(ip_geoloc_marker_directory());
$max_zoom = (int) $this->options['map_options']['maxzoom'];
$zoom = max(1, (int) $this->options['map_options']['zoom']);
$zoom_on_click = (int) $this->options['map_options']['zoom_on_click'];
$scroll_wheel_zoom = (bool) $this->options['map_options']['scrollwheelzoom'];
$dragging = (bool) $this->options['map_options']['dragging'];
$visitor_location = ip_geoloc_get_visitor_location();
if (!isset($visitor_location['latitude'])) {
$visitor_location = db_query('SELECT * FROM {ip_geoloc} WHERE ip_address = :ip_address', array(
':ip_address' => ip_address(),
))
->fetchAssoc();
}
if (empty($visitor_location['popup'])) {
$visitor_location['popup'] = $this->options['visitor_marker']['visitor_marker_balloon_text'];
}
if (strpos($visitor_location['popup'], '[visitor-location:surrounding-polygon]')) {
drupal_add_js(drupal_get_path('module', 'ip_geoloc') . '/js/ip_geoloc_pip.js');
}
$use_specified_center = !empty($this->options['map_options']['center_lat']) && !empty($this->options['map_options']['center_lon']) && empty($visitor_location['is_updated']);
if ($use_specified_center) {
$map['center'] = array(
'lat' => $this->options['map_options']['center_lat'],
'lon' => $this->options['map_options']['center_lon'],
);
}
elseif (!empty($locations) && ($center_option == IP_GEOLOC_MAP_CENTER_ON_FIRST_LOCATION || $visitor_marker_color == 'none' && count($locations) == 1)) {
$map['center'] = _ip_geoloc_get_center(reset($locations));
}
elseif (($center_option == IP_GEOLOC_MAP_CENTER_OF_LOCATIONS || $center_option == IP_GEOLOC_MAP_CENTER_OF_LOCATIONS_WEIGHTED) && !empty($locations)) {
list($center_lat, $center_lon) = ip_geoloc_center_of_locations($locations, $center_option == IP_GEOLOC_MAP_CENTER_OF_LOCATIONS_WEIGHTED);
$map['center'] = array(
'lat' => $center_lat,
'lon' => $center_lon,
);
}
if (!$use_specified_center && (empty($locations) || $center_option == IP_GEOLOC_MAP_CENTER_ON_VISITOR) && isset($visitor_location['latitude'])) {
$map['center'] = array(
'lat' => $visitor_location['latitude'],
'lon' => $visitor_location['longitude'],
);
}
if (empty($locations)) {
$ll = trim($this->options['empty_map_center']);
if (empty($ll)) {
return;
}
if ($ll != t('visitor')) {
list($map['center']['lat'], $map['center']['lon']) = preg_split("/[\\s,]+/", $ll);
}
}
else {
uasort($locations, '_ip_geoloc_plugin_style_leaflet_compare');
}
$marker_dimensions = explode('x', ip_geoloc_marker_dimensions());
$marker_width = (int) $marker_dimensions[0];
$marker_height = (int) $marker_dimensions[1];
switch (variable_get('ip_geoloc_marker_anchor_pos', 'bottom')) {
case 'top':
$marker_anchor = 0;
break;
case 'middle':
$marker_anchor = (int) (($marker_height + 1) / 2);
break;
default:
$marker_anchor = $marker_height;
}
$features = array();
$has_special_markers = $tag_css_classes || $marker_css_classes;
foreach ($locations as $location) {
$feature = array(
'type' => empty($location->type) ? 'point' : $location->type,
);
if (isset($location->title)) {
$feature['title'] = $location->title;
}
if ($feature['type'] != 'point' && !empty($this->options['vector_display']['stroke_override'])) {
$feature_options = $this->options['vector_display'];
if (module_exists('token')) {
$entity_type = empty($location->entity_type) ? 'node' : $location->entity_type;
$entity = isset($location->id) ? entity_load_single($entity_type, $location->id) : FALSE;
if ($entity) {
foreach ($feature_options as &$option) {
$option = token_replace($option, array(
$entity_type => $entity,
), array(
'clear' => TRUE,
));
}
}
}
$feature_options = array_filter($feature_options, 'strlen');
unset($feature_options['stroke_override']);
$feature['options'] = $feature_options;
}
if (isset($location->latitude) || isset($location->lat)) {
$feature['lat'] = isset($location->latitude) ? $location->latitude : $location->lat;
$feature['lon'] = isset($location->longitude) ? $location->longitude : $location->lon;
if (!empty($location->random_displacement)) {
ip_geoloc_add_random_displacement($feature, $location->random_displacement);
$circle = array(
'type' => 'circle',
'lat' => $feature['lat'],
'lon' => $feature['lon'],
'radius' => $location->random_displacement,
);
$features[] = $circle;
}
}
elseif (isset($location->component)) {
$feature['component'] = $location->component;
}
elseif (isset($location->points)) {
$feature['points'] = $location->points;
}
if ($feature['type'] != 'point') {
$feature['flags'] = LEAFLET_MARKERCLUSTER_EXCLUDE_FROM_CLUSTER;
}
elseif (!isset($feature['lat'])) {
continue;
}
if (isset($location->id)) {
$feature['feature_id'] = $location->id;
}
if (!empty($sync_flags)) {
$feature['flags'] = isset($feature['flags']) ? $feature['flags'] | $sync_flags : $sync_flags;
}
if ($enable_balloons && isset($location->balloon_text)) {
$feature['popup'] = $location->balloon_text;
}
if (!empty($location->marker_special_char) || !empty($location->marker_special_char_class)) {
$has_special_markers = TRUE;
if (!empty($location->marker_special_char)) {
$feature['specialChar'] = filter_xss_admin($location->marker_special_char);
}
if (!empty($location->marker_special_char_class)) {
$feature['specialCharClass'] = filter_xss_admin($location->marker_special_char_class);
}
}
elseif (!empty($this->options['default_marker']['default_marker_special_char']) || !empty($this->options['default_marker']['default_marker_special_char_class'])) {
$has_special_markers = TRUE;
$feature['specialChar'] = $this->options['default_marker']['default_marker_special_char'];
$feature['specialCharClass'] = $this->options['default_marker']['default_marker_special_char_class'];
}
if (!empty($location->marker_tooltip)) {
if (module_exists('leaflet_label')) {
$feature['label'] = $location->marker_tooltip;
}
else {
$has_special_markers = TRUE;
$feature['tooltip'] = $location->marker_tooltip;
}
}
if (!empty($location->regions)) {
$has_special_markers = TRUE;
$feature['regions'] = array(
0 => '',
) + $location->regions;
if (isset($location->aggregation_value)) {
$feature['aggregationValue'] = (double) $location->aggregation_value;
}
$feature['tooltip'] = empty($feature['tooltip']) ? '' : $feature['tooltip'] . "\n";
$second_last = count($feature['regions']) - 2;
if ($second_last > 0) {
$feature['tooltip'] .= $feature['regions'][$second_last] . ' - ';
}
$feature['tooltip'] .= end($feature['regions']);
}
if (!empty($location->marker_tag)) {
$feature['tag'] = $location->marker_tag;
}
if ($tag_css_classes || !empty($location->marker_classes)) {
if (empty($location->marker_classes)) {
$feature['cssClass'] = $tag_css_classes;
}
else {
$feature['cssClass'] = implode(' ', array_merge(array(
$tag_css_classes,
), $location->marker_classes));
}
}
if (isset($location->marker_color) && _ip_geoloc_is_no_marker($location->marker_color) || !isset($location->marker_color) && _ip_geoloc_is_no_marker($marker_color)) {
$has_special_markers = TRUE;
$feature['icon'] = FALSE;
}
elseif (!empty($location->marker_color) || !empty($marker_color)) {
$color = empty($location->marker_color) ? $marker_color : $location->marker_color;
$feature['icon'] = array(
'iconUrl' => $marker_path . "/{$color}.png",
'iconSize' => array(
'x' => $marker_width,
'y' => $marker_height,
),
'iconAnchor' => array(
'x' => (int) (($marker_width + 1) / 2),
'y' => $marker_anchor,
),
'popupAnchor' => array(
'x' => 0,
'y' => -$marker_height - 1,
),
);
}
$features[] = $feature;
}
if (isset($visitor_location['latitude'])) {
if ($visitor_marker_color != 'none') {
$visitor_feature = array(
'type' => 'point',
'isVisitor' => true,
'lat' => $visitor_location['latitude'],
'lon' => $visitor_location['longitude'],
'specialChar' => filter_xss_admin($this->options['visitor_marker']['visitor_marker_special_char']),
'specialCharClass' => filter_xss_admin($this->options['visitor_marker']['visitor_marker_special_char_class']),
'popup' => t('Your approximate location'),
'tooltip' => !empty($visitor_location['tooltip']) ? $visitor_location['tooltip'] : t('Your approximate location'),
'zIndex' => 9999,
'flags' => LEAFLET_MARKERCLUSTER_EXCLUDE_FROM_CLUSTER,
);
if (!empty($visitor_location['popup']) && module_exists('token')) {
$visitor_feature['popup'] = token_replace($visitor_location['popup'], $visitor_location, array());
}
if ($visitor_marker_color != '') {
if (!empty($visitor_feature['specialChar']) || !empty($visitor_feature['specialCharClass'])) {
$has_special_markers = TRUE;
}
$visitor_feature['icon'] = array(
'iconUrl' => $marker_path . "/{$visitor_marker_color}.png",
'iconSize' => array(
'x' => $marker_width,
'y' => $marker_height,
),
'iconAnchor' => array(
'x' => (int) (($marker_width + 1) / 2),
'y' => $marker_anchor,
),
'popupAnchor' => array(
'x' => 0,
'y' => -$marker_height - 1,
),
);
}
$features[] = $visitor_feature;
}
if (!empty($this->options['visitor_marker']['visitor_marker_accuracy_circle']) && !empty($visitor_location['accuracy'])) {
$visitor_accuracy_circle = array(
'type' => 'circle',
'lat' => $visitor_location['latitude'],
'lon' => $visitor_location['longitude'],
'radius' => (double) $visitor_location['accuracy'],
'popup' => !empty($visitor_location['popup']) ? $visitor_location['popup'] : t("You are within @m meters of the centre of this circle.", array(
'@m' => $visitor_location['accuracy'],
)),
'label' => !empty($visitor_location['tooltip']) ? $visitor_location['tooltip'] : t('You are within this circle'),
'zIndex' => 9998,
'flags' => LEAFLET_MARKERCLUSTER_EXCLUDE_FROM_CLUSTER,
);
$features[] = $visitor_accuracy_circle;
}
}
if (!$use_specified_center && empty($center_option) && count($features) > 1) {
unset($map['center']);
}
else {
$map['settings']['zoom'] = $zoom;
if (!empty($map['center'])) {
$map['center']['force'] = TRUE;
}
}
$map['settings']['maxZoom'] = $max_zoom;
$map['settings']['scrollWheelZoom'] = $scroll_wheel_zoom;
$map['settings']['dragging'] = $dragging;
$map['settings']['revertLastMarkerOnMapOut'] = (bool) ($sync_flags & LEAFLET_SYNC_REVERT_LAST_MARKER_ON_MAP_OUT);
$map['settings']['maxClusterRadius'] = 0;
if ($cluster_radius > 0) {
if (module_exists('leaflet_markercluster')) {
$map['settings']['maxClusterRadius'] = $cluster_radius;
$map['settings']['disableClusteringAtZoom'] = $disable_clustering_at_zoom;
$map['settings']['addRegionToolTips'] = $cluster_tooltips;
$map['settings']['hullHugFactor'] = $hull_hug_factor;
$map['settings']['touchMode'] = $cluster_touch_mode;
$map['settings']['animateAddingMarkers'] = TRUE;
if (!empty($cluster_aggregation_field)) {
$map['settings']['clusterAggregationFunction'] = $cluster_aggregation_function;
$map['settings']['clusterAggregateRanges'] = $cluster_aggregate_ranges;
$map['settings']['clusterAggregatePrecision'] = $cluster_aggregate_precision;
drupal_add_css(leaflet_markercluster_get_library_path() . '/MarkerCluster.Aggregations.css');
}
if ($allow_clusters_of_one) {
$map['settings']['allowClustersOfOne'] = TRUE;
$map['settings']['spiderfyDistanceMultiplier'] = 4.0;
}
}
else {
$display_name = $this->view
->get_human_name() . ' (' . $this->display->display_title . ')';
drupal_set_message(t('Cannot cluster markers in View %display_name, as the module Leaflet MarkerCluster is not enabled.', array(
'%display_name' => $display_name,
)), 'warning');
}
}
$zoom_ranges = array_filter($this->options['cluster_differentiator']['zoom_ranges']);
if (!empty($zoom_ranges)) {
$region_levels = array_fill(0, $max_zoom + 1, 0);
foreach ($zoom_ranges as $level => $zoom_range) {
for ($zoom = 1; $zoom <= $max_zoom; $zoom++) {
if (ip_geoloc_is_in_range($zoom, $zoom_range)) {
$region_levels[$zoom] = $level;
}
}
}
for ($z = 1; $z <= $max_zoom; $z++) {
if (empty($region_levels[$z])) {
$region_levels[$z] = $region_levels[$z - 1];
}
}
$map['settings']['regionLevels'] = $region_levels;
}
$map_id = 'ip-geoloc-map-of-view-' . $this->view->name . '-' . $this->display->id . '-' . md5(serialize($features));
drupal_add_js(drupal_get_path('module', 'leaflet') . '/leaflet.drupal.js');
if ($sync_flags !== 0) {
drupal_add_js($module_path . '/js/ip_geoloc_leaflet_sync_content.js', array(
'weight' => 2,
));
drupal_add_css($module_path . '/css/ip_geoloc_leaflet_sync_content.css');
}
if ($has_full_screen) {
if (drupal_add_library('ip_geoloc', 'leaflet-fullscreen')) {
$map['settings']['fullscreenControl'] = array(
'position' => 'topright',
);
}
}
if ($has_mini_map) {
if (drupal_add_library('ip_geoloc', 'leaflet-minimap')) {
$map['settings']['miniMap'] = array(
'autoToggleDisplay' => TRUE,
'height' => $this->options['mini_map']['height'],
'width' => $this->options['mini_map']['width'],
'position' => 'bottomright',
'toggleDisplay' => !empty($this->options['mini_map']['toggle']),
'zoomAnimation' => FALSE,
'zoomLevelOffset' => (int) $this->options['mini_map']['zoom_delta'],
'aimingRectOptions' => array(
'color' => $this->options['mini_map']['scope_color'],
'weight' => 3,
'fillOpacity' => 0.1,
),
'shadowRectOptions' => array(
'color' => '#888',
'weight' => 1,
),
);
}
}
$map['settings']['zoomIndicator'] = $zoom_indicator;
$map['settings']['zoomOnClick'] = $zoom_on_click;
$map['settings']['resetControl'] = $reset_control;
$map['settings']['clusterControl'] = $cluster_control;
$map['settings']['scaleControl'] = $scale_control;
if ($has_mini_map || $zoom_indicator || $reset_control || $cluster_control || $scale_control) {
drupal_add_js($module_path . '/js/ip_geoloc_leaflet_controls.js', array(
'weight' => 1,
));
drupal_add_css($module_path . '/css/ip_geoloc_leaflet_controls.css');
}
$map['settings']['gotoContentOnClick'] = $goto_content_on_click;
$map['settings']['openBalloonsOnHover'] = $open_balloons_on_hover;
$map['settings']['polygonAddShadowOnHover'] = $polygon_add_shadow_on_hover;
$map['settings']['shadowOnHoverEffect'] = $shadow_on_hover_effect;
$map['settings']['useTweenMaxForShadowOnHover'] = $use_tweenmax_for_shadow_on_hover;
$map['settings']['polygonFillOpacityOnHover'] = $polygon_fill_opacity_on_hover;
$map['settings']['polygonLineWeightOnHover'] = $polygon_line_weight_on_hover;
if ($goto_content_on_click) {
drupal_add_js($module_path . '/js/ip_geoloc_leaflet_goto_content_on_click.js', array(
'scope' => 'footer',
));
}
if ($open_balloons_on_hover || $polygon_add_shadow_on_hover || is_numeric($polygon_fill_opacity_on_hover) || is_numeric($polygon_line_weight_on_hover)) {
if ($polygon_add_shadow_on_hover && $use_tweenmax_for_shadow_on_hover) {
$version = $use_tweenmax_for_shadow_on_hover;
drupal_add_js("https://cdnjs.cloudflare.com/ajax/libs/gsap/{$version}/TweenMax.min.js", array(
'scope' => 'footer',
));
}
drupal_add_js($module_path . '/js/ip_geoloc_leaflet_hover.js', array(
'scope' => 'footer',
));
}
$settings = array(
'mapId' => $map_id,
'map' => $map,
'features' => $features,
);
$options = array(
'type' => 'setting',
'scope' => 'footer',
);
drupal_add_js(array(
'leaflet' => array(
$settings,
),
), $options);
libraries_load('leaflet');
drupal_alter('leaflet_map_prebuild', $settings);
if ($reset_control || $cluster_control || !empty($has_special_markers)) {
drupal_add_library('ip_geoloc', 'ip_geoloc_font_icon_libs');
drupal_add_css($module_path . '/css/ip_geoloc_leaflet_markers.css');
drupal_add_js($module_path . '/js/ip_geoloc_leaflet_tagged_marker.js', array(
'weight' => 1,
));
}
if ($zoom_on_click) {
drupal_add_js($module_path . '/js/ip_geoloc_leaflet_zoom_on_click.js', array(
'scope' => 'footer',
));
}
$output = theme('ip_geoloc_leaflet', array(
'map_id' => $map_id,
'height' => trim($this->options['map_height']),
'view' => $this->view,
));
ip_geoloc_debug(t('-- Leaflet map preparation time: %sec s', array(
'%sec' => number_format(microtime(TRUE) - $render_start, 2),
)));
return $output;
}
public function get_region_field_depth($region_field) {
if (empty($region_field['type'])) {
return 1;
}
if ($region_field['type'] === 'addressfield') {
return 4;
}
if (empty($region_field['settings']['allowed_values'])) {
return 1;
}
$depth = 0;
foreach ($region_field['settings']['allowed_values'] as $tree) {
if ($vocabulary = taxonomy_vocabulary_machine_name_load($tree['vocabulary'])) {
if ($terms = taxonomy_get_tree($vocabulary->vid, $tree['parent'])) {
foreach ($terms as $term) {
$depth = max($term->depth, $depth);
}
break;
}
}
}
return $depth + 1;
}
private function _get_zoom_titles($field_type, $label, $region_depth) {
$titles = array();
if ($field_type === 'addressfield') {
$titles[] = t('Zoom range for country');
$titles[] = t('Zoom range for administrative area (state, district, county)');
$titles[] = t('Zoom range for locality (city, town, village)');
$titles[] = t('Zoom range for post code (ZIP)');
return $titles;
}
$pos_colon = strrpos($label, ':');
$label = drupal_substr($label, $pos_colon > 0 ? $pos_colon + 1 : 0);
if ($field_type === 'taxonomy_term_reference') {
for ($level = 1; $level <= $region_depth; $level++) {
$titles[] = t('Zoom range for %field level @level', array(
'%field' => $label,
'@level' => $level,
));
}
}
else {
$titles[] = t('Zoom range for %field', array(
'%field' => $label,
));
}
return $titles;
}
private function _fill_out_location_region($field_type, &$location, $region, &$level) {
switch ($field_type) {
case 'taxonomy_term_reference':
$region_hierarchy = taxonomy_get_parents_all($region);
foreach (array_reverse($region_hierarchy) as $region_term) {
$location->regions[$level++] = trim($region_term->name);
}
break;
case 'addressfield':
if (!empty($region)) {
$format_callback = 'addressfield_format_address_generate';
if (function_exists($format_callback) && isset($region['country'])) {
$format = array();
$context = array(
'mode' => NULL,
);
addressfield_format_address_generate($format, $region, $context);
if (isset($format['country']['#options'][$region['country']])) {
$region['country'] = $format['country']['#options'][$region['country']];
}
if (isset($region['administrative_area']) && isset($format['locality_block']['administrative_area']['#options'][$region['administrative_area']])) {
$region['administrative_area'] = $format['locality_block']['administrative_area']['#options'][$region['administrative_area']];
}
}
else {
}
$location->regions = array(
1 => isset($region['country']) ? trim($region['country']) : '',
2 => isset($region['administrative_area']) ? trim($region['administrative_area']) : '',
3 => isset($region['locality']) ? trim($region['locality']) : '',
4 => isset($region['postal_code']) ? trim($region['postal_code']) : '',
);
$level = 5;
}
break;
default:
$location->regions[$level++] = trim($region);
}
}
protected function fill_out_location_regions($locations) {
if (empty($this->options['cluster_differentiator']['cluster_differentiator_fields'])) {
return;
}
$region_fields = array();
foreach ($this->options['cluster_differentiator']['cluster_differentiator_fields'] as $region_fieldname) {
$region_field = field_info_field($region_fieldname);
$region_fields[] = empty($region_field) ? $region_fieldname : $region_field;
}
if (empty($region_fields) || !reset($region_fields)) {
return;
}
foreach ($this->view->result as $key => $row) {
if (isset($locations[$key])) {
$level = 1;
foreach ($region_fields as $region_field) {
$region_values = ip_geoloc_get_view_result($this, $region_field, $key);
$field_type = isset($region_field['type']) ? $region_field['type'] : 'text';
$region = $field_type == 'addressfield' ? $region_values : end($region_values);
if (empty($region)) {
$region = '';
}
$this
->_fill_out_location_region($field_type, $locations[$key], $region, $level);
}
}
}
}
}
function _ip_geoloc_plugin_style_leaflet_refresh_cluster_fieldset_js($form, &$form_state) {
return $form['options']['style_options']['cluster_differentiator'];
}
function _ip_geoloc_get_center($location) {
if (empty($location->type) || $location->type == 'point') {
$lat = isset($location->lat) ? $location->lat : (isset($location->latitude) ? $location->latitude : 0.0);
$lon = isset($location->lon) ? $location->lon : (isset($location->longitude) ? $location->longitude : 0.0);
return array(
'lat' => $lat,
'lon' => $lon,
);
}
if (!empty($location->component[0]['points'][0])) {
return $location->component[0]['points'][0];
}
}
function _ip_geoloc_is_no_marker($marker_color) {
return isset($marker_color) && ($marker_color === '0' || $marker_color === 0 || $marker_color === FALSE);
}
function ip_geoloc_plugin_style_leaflet_map_get_info($map_name = NULL) {
return module_exists('leaflet') ? leaflet_map_get_info($map_name) : array();
}
function _ip_geoloc_plugin_style_leaflet_compare($location1, $location2) {
$weight1 = empty($location1->weight) ? 0 : $location1->weight;
$weight2 = empty($location2->weight) ? 0 : $location2->weight;
return $weight2 - $weight1;
}