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.
*/
// 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');
drupal_add_js($path . variable_get('gmap_mm_type', 'gmap') .'_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.'),
),
166
167
168
169
170
171
172
173
174
175
176
177
178
179
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
215
216
217
218
219
220
221
222
223
224
225
226
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
'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,
),
);
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.
*/
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 ($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;
}
/**
* Parse a macro style definition.
* Example: #111111/1/100/#111111/1
*/
function _gmap_parse_style($style) {
if (strpos($style, '/') === FALSE) {
// Style ref.
return $style;
}
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
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
$styles = explode('/', $style);
// @@@ Todo: Fix up old xmaps stuff. Possibly detect by looking for array length 7?
// Strip off # signs, they get added by code.
if (isset($styles[0]) && substr($styles[0], 0, 1) == '#') {
$styles[0] = substr($styles[0], 1);
}
if (isset($styles[3]) && substr($styles[3], 0, 1) == '#') {
$styles[3] = substr($styles[3], 1);
}
// Assume anything > 0 and < 1.1 was an old representation.
if ($styles[2] > 0 && $styles[2] < 1.1) {
$styles[2] = $styles[2] * 100;
}
if (isset($styles[4])) {
if ($styles[4] > 0 && $styles[4] < 1.1) {
$styles[4] = $styles[4] * 100;
}
}
return $styles;
}
/**
* 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) {
// Get a list of keys that are "multiple."
$m = array();
$multiple = module_invoke_all('gmap', 'macro_multiple', $m);
// Remove leading and trailing tags
if (substr(trim($instring), -1)==']') {
$instring = substr(trim($instring), 0, -1);
}
if (substr($instring, 0, 5)=='[gmap') {
$instring = substr($instring, 6);
}
// Chop the macro into an array
$temp = explode('|', $instring);
$m = array();
foreach ($temp as $row) {
$offset = strpos($row, '=');
if ($offset !== FALSE) {
$k = trim(substr($row, 0, $offset));
$r = trim(substr($row, $offset+1));
if (in_array($k, $multiple)) {
// Things that can appear multiple times
if (!isset($m[$k])) {
$m[$k] = array();
}
$m[$k][] = $r;
}
else {
$m[$k] = $r;
}
}
}
// Synonyms
if (isset($m['type'])) {
$m['maptype'] = $m['type'];
unset($m['type']);
}
$m['controltype'] = $m['control'];
unset($m['control']);
}
if (isset($m['feed']) && is_array($m['feed'])) {
foreach ($m['feed'] as $k => $v) {
$temp = explode('::', $v);
// Normalize url
if (substr($temp[1], 0, 1) == '/') {
$temp[1] = substr($temp[1], 1);
}
$temp[1] = url($temp[1]);
$m['feed'][$k] = array(
'markername' => $temp[0],
'url' => $temp[1],
);
}
}
// Add custom styles.
if (isset($m['style']) && is_array($m['style'])) {
foreach ($m['style'] as $k => $v) {
$temp = explode(':', $v);
$m['styles'][$temp[0]] = _gmap_parse_style($temp[1]);
}
unset($m['style']);
}
if (!isset($m['points']) || !is_array($m['points'])) $m['points'] = array();
if (!isset($m['markers']) || !is_array($m['markers'])) $m['markers'] = array();
$m['markers-temp'] = array_merge($m['points'], $m['markers']);
unset($m['points']);
unset($m['markers']);
// all shapes in 1 array
if (isset($m['circle']) && is_array($m['circle'])) {
foreach ($m['circle'] as $shape) {
$s = array('type' => 'circle');
$cp = strpos($shape, ':');
$stylestr = substr($shape, 0, $cp);
$s['style'] = _gmap_parse_style($stylestr);
$shape = substr($shape, $cp+1);
}
$tmp = explode('+', $shape);
$s['radius'] = $tmp[1] ? $tmp[1] : 100;
if ($tmp[2]) $s['numpoints'] = trim($tmp[2]);
$tmp = _gmap_str2coord($tmp[0]);
$s['center'] = $tmp[0];
$m['shapes'][] = $s;
}
unset($m['circle']);
}
// Fixup legacy lines.
if (isset($m['line1'])) {
if (!isset($m['line'])) $m['line'] = array();
$m['line'][] = $def['line_colors'][0] .':'. $m['line1'];
if (isset($m['line2'])) {
if (!isset($m['line'])) $m['line'] = array();
$m['line'][] = $def['line_colors'][1] .':'. $m['line3'];
if (isset($m['line3'])) {
if (!isset($m['line'])) $m['line'] = array();
$m['line'][] = $def['line_colors'][2] .':'. $m['line3'];
if (isset($m['line']) && is_array($m['line'])) {
foreach ($m['line'] as $shape) {
$s = array('type' => 'line');
$cp = strpos($shape, ':');
$stylestr = substr($shape, 0, $cp);
$s['style'] = _gmap_parse_style($stylestr);
$shape = substr($shape, $cp+1);
}
$s['points'] = _gmap_str2coord($shape);
$m['shapes'][] = $s;
}
unset($m['line']);
}
if (isset($m['rpolygon']) && is_array($m['rpolygon'])) {
foreach ($m['rpolygon'] as $shape) {
$s = array('type' => 'rpolygon');
$cp = strpos($shape, ':');
$stylestr = substr($shape, 0, $cp);
$s['style'] = _gmap_parse_style($stylestr);
$shape = substr($shape, $cp+1);
}
$tmp = explode('+', $shape);
if ($tmp[2]) {
$s['numpoints'] = (int)trim($tmp[2]);
$tmp = array_slice($tmp, 0, 2);
}
$shape = implode('+', $tmp);
$tmp = _gmap_str2coord($shape);
$s['center'] = $tmp[0];
$s['point2'] = $tmp[1];
$m['shapes'][] = $s;
}
unset($m['rpolygon']);
}
if (isset($m['polygon']) && is_array($m['polygon'])) {
foreach ($m['polygon'] as $shape) {
$s = array('type' => 'polygon');
$cp = strpos($shape, ':');
$stylestr = substr($shape, 0, $cp);
$s['style'] = _gmap_parse_style($stylestr);
$shape = substr($shape, $cp+1);
}
$s['points'] = _gmap_str2coord($shape);
$m['shapes'][] = $s;
}
unset($m['polygon']);
}
// Version 1 -> 2 conversion
if ($ver == 1) {
// Zoom is flipped
if (isset($m['zoom'])) {
$m['zoom'] = 18 - $m['zoom'];
if ($m['zoom'] < 1) {
$m['zoom'] = 1;
}
}
}
// Center -> latitude and longitude
if (isset($m['center']) && $m['center']) {
list($m['latitude'], $m['longitude']) = explode(',', $m['center']);
unset($m['center']);
}
// Behavior
if (isset($m['behaviour'])) {
$m['behavior'] = $m['behaviour'];
unset($m['behaviour']);
}
if (isset($m['behavior'])) {
Brandon Bergren
committed
$sep = ' ';
if (strpos($m['behavior'], ',') !== FALSE) {
// In some places, commas were used to seperate behaviors.
// This was originally an accident, but it's easy enough to support.
$sep = ',';
}
$m['behavior-temp'] = explode($sep, $m['behavior']);
$m['behavior'] = array();
foreach ($m['behavior-temp'] as $v) {
$m['behavior'][substr($v, 1)] = (substr($v, 0, 1) == '+') ? TRUE : FALSE;
}
unset($m['behavior-temp']);
}
// tcontrol now is mtc.
if (isset($m['tcontrol'])) {
if (strtolower(trim($m['tcontrol'])) == 'on') {
$m['mtc'] = 'standard';
}
else {
$m['mtc'] = 'none';
}
unset($m['tcontrol']);
}
// notype also controls mtc.
if (isset($m['behavior']['notype'])) {
if ($m['behavior']['notype']) {
$m['mtc']= 'none';
}
unset($m['behavior']['notype']);
}
// Stuff that was converted to behavior flags
// Scale control.
if (isset($m['scontrol'])) {
if (strtolower(trim($m['scontrol'])) == 'on') {
$m['behavior']['scale'] = TRUE;
}
else {
$m['behavior']['scale'] = FALSE;
}
unset($m['scontrol']);
}
// Draggability.
if (isset($m['drag'])) {
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
if (strtolower(trim($m['drag'])) == 'yes') {
$m['behavior']['nodrag'] = FALSE;
}
else {
$m['behavior']['nodrag'] = TRUE;
}
unset($m['drag']);
}
// Markers fixup
foreach ($m['markers-temp'] as $t) {
unset($markername);
// Named?
if (strpos($t, '::')) { // Single : gets handled below.
list($markername, $t) = explode('::', $t, 2);
}
// Break down into points
$points = explode('+', $t);
$offset = -1;
foreach ($points as $point) {
$marker = array();
$offset++;
$marker['options'] = array();
// Labelled?
// @@@ Gmap allows both a tooltip and a popup, how to represent?
if (strpos($point, ':')) {
list($point, $marker['text']) = explode(':', $point, 2);
$marker['text'] = theme('gmap_marker_popup', $marker['text']);
}
if (strpos($point, '%')) {
list($point, $addons) = explode('%', $point, 2);
$motemp = explode('%', $addons);
foreach ($motemp as $option) {
$marker['options'][trim($option)] = TRUE;
}
}
list($marker['latitude'], $marker['longitude']) = explode(',', $point, 2);
// Named markers get an offset too.
if (isset($markername)) {
$marker['markername'] = $markername;
$marker['offset'] = $offset;
}
$m['markers'][] = $marker;
}
}
unset($m['markers-temp']);
// Assign an id if one wasn't specified.
if (!isset($m['id'])) {
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
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
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
706
707
708
709
710
711
712
713
$m['id'] = gmap_get_auto_mapid();
}
// The macro can now be manipulated by reference.
foreach (module_implements('gmap') as $module) {
$additions = call_user_func_array($module .'_gmap', array('parse_macro', &$m));
if (!empty($additions)) {
foreach ($additions as $k => $v) {
$m[$k] = $v;
}
}
}
return $m;
}
/**
* Parse "x.xxxxx , y.yyyyyy (+ x.xxxxx, y.yyyyy ...)" into an array of points.
*/
function _gmap_str2coord($str) {
// Explode along + axis
$arr = explode('+', $str);
// Explode along , axis
$points = array();
foreach ($arr as $pt) {
list($lat, $lon) = explode(',', $pt);
$points[] = array((float)trim($lat), (float)trim($lon));
}
return $points;
}
/**
* Theme a marker popup.
* This will get called for markers embedded in macros.
*/
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 {
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
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 filter')));
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) {
if (user_access('create 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";
$contents .= "Drupal.gmap.iconpath = ". drupal_to_js(base_path() . drupal_get_path('module', 'gmap') .'/markers') .";\n";
$contents .= "Drupal.gmap.icondata = ". drupal_to_js(gmap_get_icondata()) .";\n";
file_save_data($contents, "$jspath/gmap_markers.js", FILE_EXISTS_REPLACE);
}
/**
* 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;
}
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
/**
* 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';
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
995
996
997
998
999
1000
$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');