Newer
Older
<?php
// $Id$
/**
* @file
* GMap Filters is a module to include Google Map in a module
*
* GMap filter allows the insertion of a googlemap in a module. It has
* a page to creat a macro and then a filter to convet the macro into the
* html and javascript code required to insert a google map.
*/
/**
* Define the Google Maps API version being used.
*
* Current minimum version: 2.113
*
* Minimum version last changed on: June 9 2008
*
* Reason: G_SATELLITE_3D_MAP support in gmap_addons. See http://code.google.com/apis/earth/.
*
* See http://groups.google.com/group/Google-Maps-API/web/api-version-changes
* for details on using other version numbers.
*/
define('GMAP_API_VERSION', '2.115');
/**
* Get the defaults for a gmap.
*/
function gmap_defaults() {
$defaults = array(
'width' => '300px',
'height' => '200px',
'zoom' => 3,
'maxzoom' => 14,
'controltype' => 'Small',
'align' => 'None',
'latlong' => '40,0',
'maptype' => 'Map',
'mtc' => 'standard',
'baselayers' => array('Map', 'Satellite', 'Hybrid'),
'styles' => array(
'line_default' => array('0000ff', 5, 45, '', 0, 0),
'poly_default' => array('000000', 3, 25, 'ff0000', 45),
),
'line_colors' => array('#00cc00', '#ff0000', '#0000ff'),
);
$defaults['behavior'] = array();
$m = array();
$behaviors = module_invoke_all('gmap', 'behaviors', $m);
foreach ($behaviors as $k => $v) {
$defaults['behavior'][$k] = $v['default'];
}
$defaults = array_merge($defaults, variable_get('gmap_default', array()));
return $defaults;
}
Brandon Bergren
committed
/**
* Implementation of hook_theme().
*/
function gmap_theme() {
return array(
'views_view_gmap' => array('arguments' => array('element')),
'gmap_views_marker_label' => array('arguments' => array('element')),
Brandon Bergren
committed
'gmap_marker_popup' => array('arguments' => array('label')),
Brandon Bergren
committed
'gmap_overlay_edit' => array('arguments' => array('element')),
'gmap_macrotext' => array('arguments' => array('element')),
'gmap_dimension' => array('arguments' => array('element')),
'gmap_address' => array('arguments' => array('element')),
'gmap_align' => array('arguments' => array('element')),
Brandon Bergren
committed
'gmap' => array('arguments' => array('element')),
);
}
/**
* Implementation of hook_gmap().
*/
function gmap_gmap($op, &$map) {
switch ($op) {
case 'macro':
return array(
'points' => array(
'multiple' => TRUE,
),
'markers' => array(
'multiple' => TRUE,
),
'feed' => array(
'multiple' => TRUE,
),
'style' => array(
'multiple' => TRUE,
),
);
case 'pre_theme_map':
$path = drupal_get_path('module', 'gmap') .'/js/';
if ((isset($map['behavior']['dynmarkers']) && $map['behavior']['dynmarkers']) || !empty($map['markers'])) {
static $header_set = FALSE;
if (!$header_set) {
$header_set = TRUE;
Brandon Bergren
committed
// If the user is using private download method, it's up to them to get the path set up.
if (variable_get('file_downloads', FILE_DOWNLOADS_PUBLIC) != FILE_DOWNLOADS_PUBLIC) {
$markerpath = variable_get('gmap_private_markerfile', '');
if (empty($markerpath) || !file_exists($markerpath)) {
drupal_set_message(t('GMap marker file settings are not configured properly for Private download method, markers will not work!'), 'error');
}
else {
drupal_add_js($markerpath, 'module', 'header', FALSE, TRUE, FALSE);
}
}
// With public method, we can handle all bookkeeping ourselves.
else {
$markerpath = file_create_path('js');
Brandon Bergren
committed
if (!$markerpath || !file_exists("$markerpath/gmap_markers.js")) {
gmap_regenerate_markers();
$markerpath = file_create_path('js');
}
drupal_add_js("$markerpath/gmap_markers.js", 'module', 'header', FALSE, TRUE, FALSE);
drupal_add_js($path .'icon.js');
drupal_add_js($path .'marker.js');
$mm = variable_get('gmap_mm_type', 'gmap');
// If you really really want to override the marker manager, implement
// this, take $mm by ref, and have fun. --Bdragon
if (function_exists('_gmap_markermanager_override')) {
_gmap_markermanager_override($mm);
}
drupal_add_js($path . $mm .'_marker.js');
if (isset($map['behavior']['locpick']) && $map['behavior']['locpick']) {
drupal_add_js($path .'locpick.js');
}
drupal_add_js($path .'markerloader_static.js');
}
drupal_add_js($path .'shapeloader_static.js');
drupal_add_js($path .'gmap_shapes.js');
}
drupal_add_js($path .'markerloader_georss.js');
}
break;
case 'macro_multiple':
return array('points', 'markers', 'feed', 'circle', 'rpolygon', 'polygon', 'line', 'style');
case 'behaviors':
return array(
'locpick' => array(
'title' => t('Location chooser'),
'default' => FALSE,
'help' => t('Used to activate location choosing using a gmap.'),
'internal' => TRUE,
),
'nodrag' => array(
'title' => t('Disable dragging'),
'default' => FALSE,
'help' => t('Remove the ability for the user to drag the map. If dragging is disabled, keyboard shortcuts are implicitly disabled.'),
),
'nokeyboard' => array(
'title' => t('Disable keyboard'),
'default' => TRUE,
'help' => t('Disable the keyboard shortcuts.'),
),
'nomousezoom' => array(
'title' => t('Disable mousezoom'),
'default' => FALSE,
'help' => t('Disable using the scroll wheel to zoom the map.'),
),
Brandon Bergren
committed
'nocontzoom' => array(
'title' => t('Disable Continuous Zoom'),
'default' => FALSE,
'help' => t('Disable dynamically resizing images while waiting for tiles to load when zooming.'),
),
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
'autozoom' => array(
'title' => t('Use AutoZoom'),
'default' => FALSE,
'help' => t('Automatically zoom the map to fit all markers when markers are added.'),
),
'dynmarkers' => array(
'title' => t('Unconditionally enable marker interface'),
'default' => FALSE,
'help' => t('Load the marker loader system even if no markers to load are detected. Useful if you are injecting markers from somewhere else.'),
),
'overview' => array(
'title' => t('Enable Overview Map'),
'default' => FALSE,
'help' => t('Enable the "overview map" in the bottom right corner.'),
'previewable' => TRUE,
),
/* 'notype' => array(
'title' => t('Disable map type control'),
'default' => FALSE,
'help' => t('Removes the map type control from the upper right corner. Recommended for very narrow maps.'),
'previewable' => TRUE,
), */
'collapsehack' => array(
'title' => t('Work around bugs when maps appear in collapsible fieldsets'),
'default' => FALSE,
'help' => t('Enabling this will work around some issues that can occur when maps appear inside collapsible fieldsets.'),
),
// Note to myself, who keeps forgetting what a scale control actually IS.:
// |------------ 1mi ------------|
'scale' => array(
'title' => t('Add scale control to map.'),
'default' => FALSE,
'help' => t('Adds a scale control to the map in the default position.'),
'previewable' => TRUE,
),
'extramarkerevents' => array(
'title' => t('Enable extra marker events.'),
'default' => FALSE,
'help' => t('Used for advanced javascript work, this will enable the <em>mouseovermarker</em>, <em>mouseoutmarker</em>, and <em>dblclickmarker</em> events.'),
'internal' => TRUE,
),
'clickableshapes' => array(
'title' => t('Enable clickable shapes.'),
'default' => FALSE,
'help' => t('Used for advanced javascript work, this will enable the <em>clickshape</em> event.'),
'internal' => TRUE,
),
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
);
break;
case 'baselayers':
$map['Google']['Map'] = array(
'title' => t('Map: Standard street map.'),
'default' => TRUE,
'help' => t('The standard default street map. Internal name: G_NORMAL_MAP'),
);
$map['Google']['Satellite'] = array(
'title' => t('Satellite: Standard satellite map.'),
'default' => TRUE,
'help' => t('Satellite view without street overlay. Internal name: G_SATELLITE_MAP'),
);
$map['Google']['Hybrid'] = array(
'title' => t('Hybrid: Hybrid satellite map.'),
'default' => TRUE,
'help' => t('Satellite view with street overlay. Internal name: G_HYBRID_MAP'),
);
$map['Google']['Physical'] = array(
'title' => t('Terrain: Physical feature map.'),
'default' => FALSE,
'help' => t('Map with physical data (terrain, vegetation.) Internal name: G_PHYSICAL_MAP'),
);
break;
}
}
/**
* Set up the HTML header for GMap.
* If you are going to include a custom JS file that extends GMap, you probabaly
* want to call this first to ensure that the core js files have been added.
*/
function _gmap_doheader() {
static $gmap_initialized = FALSE;
if ($gmap_initialized) {
return;
}
$gmap_path = drupal_get_path('module', 'gmap');
drupal_add_css($gmap_path .'/gmap.css');
drupal_add_js($gmap_path .'/js/gmap.js');
$mm = variable_get('gmap_mm_type', 'gmap');
// If you really really want to override the marker manager, implement
// this, take $mm by ref, and have fun. --Bdragon
if (function_exists('_gmap_markermanager_override')) {
_gmap_markermanager_override($mm);
}
if ($mm=='clusterer') {
drupal_add_js($gmap_path .'/js/icon.js');
drupal_add_js($gmap_path .'/thirdparty/Clusterer2.js');
}
drupal_add_js($gmap_path .'/js/marker.js');
drupal_add_js($gmap_path .'/js/'. $mm .'_marker.js');
$mms = variable_get('gmap_markermanager', array());
if (empty($mms[$mm])) {
$mms[$mm] = array();
}
drupal_add_js(array('gmap_markermanager' => $mms[$mm]), 'setting');
// @@@
drupal_add_js($gmap_path .'/js/poly.js');
Brandon Bergren
committed
global $language;
$query = array(
'file' => 'api',
'v' => variable_get('gmap_api_version', GMAP_API_VERSION),
'key' => gmap_get_key(),
'hl' => $language->language,
);
Brandon Bergren
committed
drupal_set_html_head('<script src="'. check_url(url('http://maps.google.com/maps', array('query' => $query))) .'" type="text/javascript"></script>');
$gmap_initialized = TRUE;
}
/**
* Convert a macro string into a GMap array.
*
* @param $instring
* Macro to process.
* @param $ver
* Version to treat macro as.
* Set to 1 when processing very old macros, otherwise leave as is.
* @return
* A GMap array.
*/
function gmap_parse_macro($instring, $ver = 2) {
Brandon Bergren
committed
require_once drupal_get_path('module', 'gmap') .'/gmap_parse_macro.inc';
return _gmap_parse_macro($instring, $ver);
}
/**
* Theme a marker popup.
* This will get called for markers embedded in macros.
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
*/
function theme_gmap_marker_popup($label) {
return $label;
}
/**
* Location chooser utility function.
*
* Creates a map that can be interactively used to fill a form with a
* location (latitude, longitude and zoom level).
*
* Note: This is a utility function designed for location.module, there is no
* guarantee it will not be removed eventually.
*
* @param $map
* Either a macro to use as the base map for setting a location, or an already set map associative array.
* @param $form
* A formset associative array. Cannot be more than one deep.
* @param $fields
* An associative array for the field names. 'latitude', 'longitude'=>name of respective array, 'address' is optional.
* @return
* A string with the google map code to be inserted onto the page.
*
*/
function gmap_set_location($map, &$form, $fields) {
static $ctr = 0;
$ctr++;
if (!is_array($map)) {
$map = array_merge(gmap_defaults(), gmap_parse_macro($map));
}
$id = 'loc'. $ctr;
$map['id'] = $id;
// This is a locpick map.
$map['behavior']['locpick'] = TRUE;
$element = array(
'#type' => 'gmap',
'#map' => $map['id'],
'#settings' => $map,
);
$form[$fields['latitude']]['#map']=$id;
gmap_widget_setup($form[$fields['latitude']], 'locpick_latitude');
$form[$fields['longitude']]['#map']=$id;
gmap_widget_setup($form[$fields['longitude']], 'locpick_longitude');
if (isset($fields['address'])) {
$form[$fields['address']]['#map'] = $id;
gmap_widget_setup($form[$fields['address']], 'locpick_address');
}
return theme('gmap', $element);
}
/**
* Handle filter preparation.
*/
function _gmap_prepare($intext) {
$out = FALSE;
$matches = array();
preg_match_all('/\[gmap([^\[\]]+ )* \] /x', $intext, $matches);
$i = 0;
while (isset($matches[1][$i])) {
$out[0][$i] = $matches[0][$i];
if ($matches[1][$i][0] == '1') {
$ver = 1;
$matches[1][$i] = substr($matches[0][$i], 1);
}
else {
$ver = 2;
}
$map = array('#settings' => gmap_parse_macro($matches[1][$i], $ver));
$out[1][$i] = theme('gmap', $map);
$i++;
} // endwhile process macro
return $out;
}
/**
* Make sure a string is a valid css dimension.
*/
function gmap_todim($instring) {
if (!is_string($instring)) {
return FALSE;
}
$s = strtolower(trim($instring));
if (preg_match('/^([\d.]+)\s*(em|ex|px|in|cm|mm|pt|pc|%)$/', $s, $matches)) {
return $matches[1] . $matches[2];
}
else {
return FALSE;
}
}
/**
* Ensure a textfield is a valid css dimension string.
*/
function gmap_dimension_validate(&$elem, &$form_state) {
$value = gmap_todim($elem['#value']);
if ($value) {
// Normalize the css dimension string.
form_set_value($elem, $value, $form_state);
}
else {
form_error($elem, t('The specified value is not a valid CSS dimension.'));
}
}
/**
* Implementation of hook_filter().
*/
function gmap_filter($op, $delta = 0, $format = -1, $text = '') {
switch ($op) {
case 'list':
return (array(0 => t('GMap macro expander')));
case 'name':
return t('Google map filter');
case 'description':
return t('Converts a Google Map macro into the HTML required for inserting a Google Map.');
case 'process':
$gmaps = _gmap_prepare($text); //returns an array of $tables[0] = table macro $table[1]= table html
if ($gmaps) { // there are table macros in this node
return str_replace($gmaps[0], $gmaps[1], $text);
}
else {
return $text;
}
case 'prepare':
return $text;
case 'no cache':
return TRUE; // @@@ Possibly improve efficiency in the future?
}
}
/**
* Implementation of hook_filter_tips().
*/
function gmap_filter_tips($delta, $format, $long = FALSE) {
Brandon Bergren
committed
if (user_access('create gmap macro')) { // only display macro if user can create one
return t('Insert Google Map macro.') .'<a href="'. url('map/macro') .'" target="_blank" >'. t('Create a macro') .'</a>';
}
else {
return t('Insert Google Map macro.');
}
}
/**
* Implementation of hook_menu().
*/
function gmap_menu() {
$items['admin/settings/gmap'] = array(
'title' => 'GMap',
'description' => 'Configure GMap settings',
'page callback' => 'drupal_get_form',
'page arguments' => array('gmap_admin_settings'),
'file' => 'gmap_settings_ui.inc',
'access arguments' => array('administer site configuration'),
'type' => MENU_NORMAL_ITEM,
);
return $items;
* Regenerate the markerdata file.
function gmap_regenerate_markers() {
$contents = '';
// Create the js/ within the files folder.
$jspath = file_create_path('js');
file_check_directory($jspath, FILE_CREATE_DIRECTORY);
$contents .= "// GMap marker image data.\n";
Brandon Bergren
committed
$contents .= "Drupal.gmap.iconpath = ". drupal_to_js(base_path() . variable_get('gmap_markerfiles', drupal_get_path('module', 'gmap') .'/markers')) .";\n";
$contents .= "Drupal.gmap.icondata = ". drupal_to_js(gmap_get_icondata(TRUE)) .";\n";
file_save_data($contents, "$jspath/gmap_markers.js", FILE_EXISTS_REPLACE);
// Also regenerate the cached marker titles array
gmap_get_marker_titles(TRUE);
}
/**
* Implementation of hook_flush_caches().
*/
function gmap_flush_caches() {
gmap_regenerate_markers();
}
/**
* Implementation of hook_elements().
*/
function gmap_elements() {
return array(
'gmap' => array(
'#input' => FALSE, // This isn't a *form* input!!
'#settings' => array_merge(gmap_defaults(), array(
'points' => array(),
'pointsOverlays' => array(),
'lines' => array(),
)),
),
'gmap_macrotext' => array(
'#input' => TRUE,
'#gmap_newtype' => 'textarea',
'#theme' => 'gmap_macrotext',
'gmap_overlay_edit' => array('#input' => TRUE, '#process' => array('process_gmap_overlay_edit')),
Brandon Bergren
committed
'gmap_style' => array('#input' => TRUE, '#tree' => TRUE, '#gmap_style_type' => 'poly', '#process' => array('process_gmap_style')),
'gmap_address' => array('#input' => TRUE, '#process' => array('process_gmap_address')),
Brandon Bergren
committed
'gmap_align' => array('#input' => TRUE, '#process' => array('process_gmap_align')),
'gmap_latitude' => array('#input' => TRUE, '#gmap_newtype' => 'textfield', '#process' => array('process_gmap_control')),
'gmap_longitude' => array('#input' => TRUE, '#gmap_newtype' => 'textfield', '#process' => array('process_gmap_control')),
'gmap_latlon' => array('#input' => TRUE, '#gmap_newtype' => 'textfield', '#process' => array('process_gmap_control')),
Brandon Bergren
committed
'gmap_markerchooser' => array('#input' => TRUE, '#process' => array('process_gmap_markerchooser')),
'gmap_dimension' => array('#input' => TRUE, '#gmap_newtype' => 'textfield', '#process' => array('process_gmap_control'), '#element_validate' => array('gmap_dimension_validate')),
);
}
/**
* Generic gmap control #process function.
*/
Brandon Bergren
committed
function process_gmap_control($element, $edit, &$form_state, $complete_form) {
$control = substr($element['#type'], 5);
$element['#type'] = $element['#gmap_newtype'];
unset($element['#gmap_newtype']);
Brandon Bergren
committed
gmap_widget_setup($element, $control);
// Attempt to run any #process handlers of our transmogrified type.
// However, if we aren't the only #process handler, we assume someone else
// is taking care of setting up any default handlers.
$chain = FALSE;
if (count($element['#process']) == 1) {
// Unset #process so we can pull in the default.
unset($element['#process']);
$chain = TRUE;
}
// Inherit #input from the new type.
unset($element['#input']);
// Merge in the defaults for the target element type.
$element += _element_info($element['#type']);
if (isset($element['#input']) && $element['#input']) {
if (isset($element['#process']) && $chain) {
// Chain process.
foreach ($element['#process'] as $process) {
if (function_exists($process)) {
$form = $process($element, $edit, $form_state, $complete_form);
}
}
}
Brandon Bergren
committed
}
return $element;
}
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
/**
* Style fieldset #process function.
*/
function process_gmap_style($element) {
$isline = ($element['#gmap_style_type'] == 'line');
// Stroke color
$element[0] = array(
'#type' => 'textfield',
'#size' => 6,
'#maxlength' => 6,
'#field_prefix' => '#',
'#title' => t('Stroke color'),
'#value' => $element['#value'][0],
'#attributes' => array('class' => 'gmap_style'),
);
// Stroke weight
$element[1] = array(
'#type' => 'textfield',
'#title' => t('Stroke weight'),
'#description' => t('Thickness of line, in pixels.'),
'#size' => 3,
'#maxlength' => 3,
'#field_suffix' => t('px'),
'#value' => $element['#value'][1],
'#attributes' => array('class' => 'gmap_style'),
);
// Stroke opacity
$element[2] = array(
'#type' => 'textfield',
'#title' => t('Stroke opacity'),
'#size' => 3,
'#maxlength' => 3,
'#field_suffix' => '%',
'#value' => $element['#value'][2],
'#attributes' => array('class' => 'gmap_style'),
);
// Fill color
$element[3] = array(
'#type' => 'textfield',
'#title' => t('Fill color'),
'#description' => t('Hex color value for fill color. Example: #<em>00AA33</em>'),
'#size' => 6,
'#maxlength' => 6,
'#field_prefix' => '#',
'#disabled' => $isline,
'#attributes' => array('class' => 'gmap_style'),
);
$element[4] = array(
'#type' => 'textfield',
'#title' => t('Fill opacity'),
'#description' => t('Opacity of fill, from 0 to 100%.'),
'#size' => 3,
'#maxlength' => 3,
'#field_suffix' => '%',
'#disabled' => $isline,
'#attributes' => array('class' => 'gmap_style'),
);
unset($element['#input']);
$element += _element_info('fieldset');
return $element;
}
/**
* Theme a gmap_style fieldset.
*/
function theme_gmap_style($element) {
// Fieldsets print #value at the end, so we need to empty it out.
// Otherwise, it puts "Array" at the end of the fieldset.
$element['#value'] = '';
return theme('fieldset', $element, $element['#children']);
}
/**
* Overlay editor #process function.
*/
function process_gmap_overlay_edit($element) {
// Conver the root element into a fieldset.
$element['#type'] = 'fieldset';
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
$element['#title'] = t('Overlay editor');
}
$element['#tree'] = TRUE;
$element['mapclicktype'] = array(
'#type' => 'select',
'#title' => t('Click map'),
'#map' => $element['#map'],
'#options' => array(
'Points' => t('Points'),
'Lines' => t('Lines'),
'Circles' => t('Circles'),
'GPolygon' => t('Filled Polygons'),
),
);
gmap_widget_setup($element['mapclicktype'], 'overlayedit_mapclicktype');
$element['markerclicktype'] = array(
'#type' => 'select',
'#title' => t('Click marker / segment'),
'#map' => $element['#map'],
'#options' => array(
'Remove' => t('Remove'),
// 'updatestyle' => t('Update Styles'),
// 'removestyle' => t('Remove Styles'),
'Edit Info' => t('Edit Info'),
),
);
gmap_widget_setup($element['markerclicktype'], 'overlayedit_markerclicktype');
$element['marker'] = array(
'#type' => 'select',
'#map' => $element['#map'],
'#options' => gmap_get_marker_titles(),
'#title' => t('Marker'),
'#theme' => 'gmap_overlay_edit',
);
gmap_widget_setup($element['marker'], 'overlayedit');
$element['linestyle'] = array(
'#type' => 'gmap_style',
'#title' => t('Line style'),
'#gmap_style_type' => 'line',
'#default_value' => array('0000ff', 5, 45, '', ''), // @@@
);
gmap_widget_setup($element['linestyle'], 'overlayedit_linestyle', $element['#map']);
$element['linestyle']['linestyle_apply'] = array(
'#tree' => FALSE,
'#type' => 'checkbox',
'#title' => t('Use for new and changed lines'),
'#default_value' => FALSE,
);
gmap_widget_setup($element['linestyle']['linestyle_apply'], 'overlayedit_linestyle_apply', $element['#map']);
$element['polystyle'] = array(
'#type' => 'gmap_style',
'#title' => t('Polygon style'),
'#gmap_style_type' => 'poly',
'#default_value' => array('000000', 3, 25, 'ff0000', 45), // @@@
);
gmap_widget_setup($element['polystyle'], 'overlayedit_polystyle', $element['#map']);
$element['polystyle']['polystyle_apply'] = array(
'#tree' => FALSE,
'#type' => 'checkbox',
'#title' => t('Use for new and changed polygons'),
'#default_value' => FALSE,
);
gmap_widget_setup($element['polystyle']['polystyle_apply'], 'overlayedit_polystyle_apply', $element['#map']);
return $element;
}
/**
* Alignment selector #process function.
*/
function process_gmap_align($element) {
$element['#type'] = 'select';
gmap_widget_setup($element, 'align');
$element['#options'] = drupal_map_assoc(array('None', 'Right', 'Left', 'Center'));
$element['#theme'] = 'gmap_align';
return $element;
}
/**
* Address widget #process function.
*/
function process_gmap_address($element) {
$element['#type'] = 'textfield';
gmap_widget_setup($element, 'address');
$element['#theme'] = 'gmap_address';
return $element;
}
/**
* Marker chooser #process function.
*/
function process_gmap_markerchooser($element) {
$element['#type'] = 'select';
$element['#options'] = gmap_get_marker_titles();
return $element;
}
/**
* Overlay editor theme function.
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
*/
function theme_gmap_overlay_edit($element) {
$path = drupal_get_path('module', 'gmap');
drupal_add_js($path .'/js/gmap.js');
drupal_add_js($path .'/js/gmap_shapes.js');
drupal_add_js($path .'/js/overlay_edit.js');
return theme('select', $element);
}
/**
* Perform some normalization on the map object
* to prevent errors.
*/
function gmap_map_cleanup(&$map) {
// Google is picky about this one.
$map['zoom'] = (int)$map['zoom'];
// Normalize latitude / longitude
if ($map['latlong']) {
$map['latlon'] = $map['latlong'];
unset($map['latlong']);
}
if (isset($map['latlon']) && (!isset($map['latitude']) || !isset($map['longitude']))) {
list($map['latitude'], $map['longitude']) = explode(',', $map['latlon']);
}
unset($map['latlon']);
foreach ($map['baselayers'] as $k => $v) {
if (!$v) {
unset($map['baselayers'][$k]);
}
}
}
function theme_gmap_macrotext($element) {
drupal_add_js(drupal_get_path('module', 'gmap') .'/js/macro.js');
// @@@
drupal_add_js(drupal_get_path('module', 'gmap') .'/js/macrobuilder.js');
return theme('textarea', $element);
}
function theme_gmap_address($element) {
drupal_add_js(drupal_get_path('module', 'gmap') .'/js/address.js');
return theme('textfield', $element);
}
function theme_gmap_align($element) {
drupal_add_js(drupal_get_path('module', 'gmap') .'/js/align.js');
return theme('select', $element);
}
/**
* Gmap element theme hook
*/
function theme_gmap($element) {
// Track the mapids we've used already.
static $mapids = array();
// Convert from raw map array if needed.
if (!isset($element['#settings'])) {
$element = array(
'#settings' => $element,
);
}
if (isset($element['#map']) && $element['#map']) {
// The default mapid is #map.
$mapid = $element['#map'];
if (isset($element['#settings']['id'])) {
// Settings overrides it.
$mapid = $element['#settings']['id'];
}
if (!$mapid) {
// Hmm, no mapid. Generate one.
$mapid = gmap_get_auto_mapid();
// Push the mapid back into #map.
$element['#map'] = $mapid;
gmap_widget_setup($element, 'gmap', $mapid);
if (!$element['#settings']) {
$element['#settings'] = array();
}
// Push the mapid back into #settings.
$element['#settings']['id'] = $mapid;
$mapdefaults = gmap_defaults();
$map = array_merge($mapdefaults, $element['#settings']);
// Styles is a subarray.
if (isset($element['#settings']['styles'])) {
$map['styles'] = array_merge($mapdefaults['styles'], $element['#settings']['styles']);
}
Rebecca White
committed
// Add a class around map bubble contents.
Brandon Bergren
committed
// @@@ Bdragon sez: Becw, this doesn't belong here. Theming needs to get fixed instead..
if (isset($map['markers'])) {
foreach ($map['markers'] as $i => $marker) {
$map['markers'][$i]['text'] = '<div class="gmap-popup">' . $marker['text'] . '</div>';
}
Rebecca White
committed
}
switch (strtolower($map['align'])) {
case 'left':
Brandon Bergren
committed
$element['#attributes']['class'] .= ' gmap-left';
Brandon Bergren
committed
$element['#attributes']['class'] .= ' gmap-right';
break;
case 'center':
case 'centre':
Brandon Bergren
committed
$element['#attributes']['class'] .= ' gmap-center';
}
$style = array();
$style[] = 'width: '. $map['width'];
$style[] = 'height: '. $map['height'];
$element['#attributes']['class'] = trim($element['#attributes']['class'] .' gmap gmap-map gmap-'. $mapid .'-gmap');
// Some markup parsers (IE) don't handle empty inners well. Use the space to let users know javascript is required.
// @@@ Bevan sez: Google static maps could be useful here.
// @@@ Bdragon sez: Yeah, would be nice, but hard to guarantee functionality. Not everyone uses the static markerloader.
$o = '<div style="'. implode('; ', $style) .';" id="'. $element['#id'] .'"'. drupal_attributes($element['#attributes']) .'>'. t('Javascript is required to view this map.') .'</div>';
// $map can be manipulated by reference.
foreach (module_implements('gmap') as $module) {
call_user_func_array($module .'_gmap', array('pre_theme_map', &$map));
}
if (isset($mapids[$element['#map']])) {
drupal_set_message(t('Duplicate map detected! GMap does not support multiplexing maps onto one MapID! GMap MapID: %mapid', array('%mapid' => $element['#map'])), 'error');
// Return the div anyway. All but one map for a given id will be a graymap,
// because obj.map gets stomped when trying to multiplex maps!
return $o;
}
$mapids[$element['#map']] = TRUE;
// Inline settings extend.
$o .= '<script type="text/javascript">'."\n";
$o .= "/* <![CDATA[ */\n";
Brandon Bergren
committed
$o .= 'jQuery.extend(true, Drupal, { settings: '. drupal_to_js(array('gmap' => array($element['#map'] => $map))) ." });\n";
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
$o .= "/* ]]> */\n";
$o .= "</script>\n";
return $o;
}
/**
* Set up widget.
* This function will change a form element's ID so it is found
* by the GMap handlers system.
* @param &$element
* The form element to modify.
* @param $type
* The gmap widget type to map to.
* @param $map
* The map id. If not defined, $element['#map'] will be used.
* @return
* None.
*/
function gmap_widget_setup(&$element, $type, $map=NULL) {
if (!$map) {
if (isset($element['#map'])) {
$map = $element['#map'];
}
else {
// Hmm, missing #map. Try to figure it out.
if (isset($element['#settings']['id'])) {
$map = $element['#settings']['id'];
}
}
}
if (!isset($element['#attributes']['class'])) {
$element['#attributes']['class'] = '';
}
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
$element['#attributes']['class'] = trim(implode(' ', array(
$element['#attributes']['class'],
'gmap-control',
'gmap-'. $type,
)));
$element['#id'] = gmap_get_id($map, $type);
$element['#map'] = $map;
}
/**
* Get a CSS id for a map and type.
* Since CSS ids have to be unique, GMap related IDs are assigned by
* this function.
*/
function gmap_get_id($map, $type) {
static $serial = array();
if (!isset($serial[$map])) {
$serial[$map] = array();
}
if (!isset($serial[$map][$type])) {
$serial[$map][$type] = -1;
}
$serial[$map][$type]++;
return 'gmap-'. $map .'-'. $type . $serial[$map][$type];
}
/**
* Generate a dynamic map identifier.
*/
function gmap_get_auto_mapid() {
static $auto = 0;
$auto++;
return 'auto'. $auto .'map';
}
/**
* Get the list of marker titles.
*/
function gmap_get_marker_titles($reset = FALSE) {
static $titles;
if (!reset) {
if (is_array($titles)) {
return $titles;
}
$cached = cache_get('gmap_marker_titles', 'cache');