gmap_views.module

Tracking 5.x-1.x branch
  1. drupal
    1. 5 contributions/gmap/gmap_views.module

GMap Views: A Views Style plugin providing a GMap view.

Functions & methods

NameDescription
gmap_views_gmapImplementation of hook_gmap().
gmap_views_query_alterImplementation of hook_views_query_alter(). We need to add in the node type so we can determine markers.
gmap_views_validateValidate a GMap View. GMap Views requires one of the following:
gmap_views_views_style_pluginsImplementation of hook_views_style_plugins().
theme_gmap_views_marker_labelTheme a marker label.
theme_views_view_gmapDisplay the results of a view in a Google Map.
_gmap_views_find_coords_idsHelper function to find a valid latitude and longitude in this field
_gmap_views_get_lat_long_from_idsHelper function to find actual lat and lon values from the work done in _gmap_views_find_coords_ids

File

View source
  1. <?php
  2. /**
  3. * @file
  4. * GMap Views: A Views Style plugin providing a GMap view.
  5. */
  6. /**
  7. * Implementation of hook_views_style_plugins().
  8. */
  9. function gmap_views_views_style_plugins() {
  10. return array(
  11. 'gmap' => array(
  12. 'name' => t('Gmap View'),
  13. 'theme' => 'views_view_gmap',
  14. 'needs_fields' => true,
  15. 'validate' => 'gmap_views_validate',
  16. )
  17. );
  18. }
  19. /**
  20. * Implementation of hook_gmap().
  21. */
  22. function gmap_views_gmap($op, &$map) {
  23. switch ($op) {
  24. case 'behaviors':
  25. return array(
  26. 'fatmarkers' => array(
  27. 'title' => t('Views "fat" markers'),
  28. 'default' => FALSE,
  29. 'help' => t('Enabling this flag will pass the raw views data with a marker for use with custom manipulation code. Hook the preparemarker event to make use of this.'),
  30. 'internal' => TRUE,
  31. ),
  32. );
  33. case 'pre_theme_map':
  34. // Don't pass the gmap_view settings to the client.
  35. unset($map['settings']['gmap_view']);
  36. break;
  37. }
  38. }
  39. /**
  40. * Validate a GMap View.
  41. * GMap Views requires one of the following:
  42. * - Location: Lat and Location: Lon
  43. * - Two columns, one titled t('Latitude'), one titled t('Longitude')
  44. * - A module that can transform a field into lat, long coordinates
  45. */
  46. function gmap_views_validate($type, $view, $form) {
  47. $ids = _gmap_views_find_coords_ids($view);
  48. if (!($ids['lat'] && $ids['lon']) && !(isset($ids['module']))) {
  49. form_error($form["$type-info"][$type .'_type'],
  50. t('GMap View requires: either "Location: Latitude" and "Location: Longitude" or a field titled "Latitude" and a field titled "Longitude"'));
  51. }
  52. return views_ui_plugin_validate_list($type, $view, $form);
  53. }
  54. /**
  55. * Display the results of a view in a Google Map.
  56. */
  57. function theme_views_view_gmap($view, $results) {
  58. // Work when multiple views are displayed at once.
  59. $mapid = "view_gmap_{$view->name}_{$view->build_type}";
  60. // Fields are used to render the markers.
  61. $fields = _views_get_fields();
  62. // find the ids of the column we want to use
  63. $point_ids = _gmap_views_find_coords_ids($view);
  64. if (isset($view->gmap_macro) && $view->gmap_macro) {
  65. $thismap = array(
  66. '#map' => $mapid,
  67. '#settings' => array_merge(gmap_defaults(), gmap_parse_macro($view->gmap_macro)),
  68. );
  69. if ($thismap['#settings']['behavior']['views_autocenter']) {
  70. // Find the first valid location.
  71. foreach ($results as $entry) {
  72. $location = _gmap_views_get_lat_long_from_ids($entry, $point_ids);
  73. if (($location['lat']) && ($location['lon'])) {
  74. // Set default location for map
  75. $thismap['#settings']['latitude'] = $location['lat'];
  76. $thismap['#settings']['longitude'] = $location['lon'];
  77. // Break loop because we have what we want.
  78. break;
  79. }
  80. }
  81. }
  82. }
  83. else if (!empty($view->gmap_map)) {
  84. $thismap = $view->gmap_map;
  85. }
  86. else {
  87. $thismap = array(
  88. '#map' => $mapid,
  89. '#settings' => gmap_defaults(),
  90. );
  91. }
  92. $fatmarkers = (isset($thismap['#settings']['behavior']['fatmarkers']) && $thismap['#settings']['behavior']['fatmarkers']);
  93. $markers = array();
  94. if ($fatmarkers) {
  95. $thismap['#settings']['viewfields'] = $view->field;
  96. $datafields = array();
  97. foreach ($view->field as $field) {
  98. if ($fields[$field['id']]['visible'] !== FALSE) {
  99. $datafields[] = $field['queryname'];
  100. }
  101. }
  102. }
  103. $markermode = $thismap['#settings']['markermode'];
  104. $markertypes = variable_get('gmap_node_markers', array());
  105. foreach ($results as $entry) {
  106. $type = $entry->gmap_node_type;
  107. $location = _gmap_views_get_lat_long_from_ids($entry, $point_ids);
  108. if (($location['lat']) && ($location['lon'])) {
  109. if ($fatmarkers) {
  110. $data = array();
  111. foreach ($view->field as $field) {
  112. if ($fields[$field['id']]['visible'] !== FALSE) {
  113. $data[] = views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $entry, $view);
  114. }
  115. }
  116. $themarker = array(
  117. 'markername' => isset($markertypes[$type]) ? $markertypes[$type] : 'drupal',
  118. 'latitude' => $location['lat'],
  119. 'longitude' => $location['lon'],
  120. 'view' => array_values($data),
  121. );
  122. if (isset($entry->gmap_taxonomy_marker) && !empty($entry->gmap_taxonomy_marker)) {
  123. $themarker['markername'] = $entry->gmap_taxonomy_marker;
  124. }
  125. }
  126. else {
  127. // Common
  128. $themarker = array(
  129. 'markername' => isset($markertypes[$type]) ? $markertypes[$type] : 'drupal',
  130. 'latitude' => $location['lat'],
  131. 'longitude' => $location['lon']
  132. );
  133. if (isset($entry->gmap_taxonomy_marker) && !empty($entry->gmap_taxonomy_marker)) {
  134. $themarker['markername'] = $entry->gmap_taxonomy_marker;
  135. }
  136. // Popup
  137. if ($markermode == 1) {
  138. // @@@ TODO: Switch to using views_theme sometime. Unfortunately, it changes the function prototype.. :-/
  139. //$marker_popup = views_theme('gmap_views_marker_label', $view->name, $view, $fields, $entry);
  140. $marker_popup = theme('gmap_views_marker_label', $view, $fields, $entry);
  141. // add themed HTML to either text or tabs depending on whether or not
  142. // it was an array.
  143. if (is_array($marker_popup)) {
  144. // Tabbed.
  145. $themarker['tabs'] = $marker_popup;
  146. }
  147. else {
  148. $themarker['text'] = $marker_popup;
  149. }
  150. }
  151. // Link
  152. else if ($markermode == 2) {
  153. $themarker['link'] = url('node/'. $entry->nid);
  154. }
  155. }
  156. if (isset($entry->node_title)) {
  157. $themarker['opts']['title'] = $entry->node_title;
  158. }
  159. $markers[] = $themarker;
  160. }
  161. }
  162. $thismap['#settings']['markers'] = $markers;
  163. $output .= theme('gmap', $thismap);
  164. return $output;
  165. }
  166. /**
  167. * Theme a marker label.
  168. */
  169. function theme_gmap_views_marker_label($view, $fields, $entry) {
  170. $marker_label = '';
  171. foreach ($view->field as $field) {
  172. $marker_label .= '<div class="gmap-popup '. $field['field'] .'">'. views_theme_field('views_handle_field', $field['queryname'], $fields, $field, $entry, $view) .'</div>';
  173. }
  174. return $marker_label;
  175. }
  176. /**
  177. * Helper function to find a valid latitude and longitude in this field
  178. */
  179. function _gmap_views_find_coords_ids($view) {
  180. $ids = array();
  181. $copy = (array) $view;
  182. foreach ($copy['field'] as $key => $field) {
  183. if (!is_numeric($key)) {
  184. continue; // skip the 'count', etc.
  185. }
  186. // we check to see if the field is a location:lat field or titled Latitude
  187. if ($field['id'] == 'location.latitude' || $field['label'] == t('Latitude')) {
  188. $ids['lat'] = $field['queryname'];
  189. }
  190. if ($field['id'] == 'location.longitude' || $field['label'] == t('Longitude')) {
  191. $ids['lon'] = $field['queryname'];
  192. }
  193. // see if any module will take on the task of adding lat-lon to the view
  194. foreach (module_implements('gmap_views_handle_field') as $module) {
  195. if ($res = module_invoke($module, 'gmap_views_handle_field', 'discover', $field)) {
  196. $ids['module'] = array(
  197. 'module' => $module,
  198. 'field' => $field['queryname'],
  199. 'extra' => $res,
  200. );
  201. }
  202. }
  203. }
  204. return $ids;
  205. }
  206. /**
  207. * Helper function to find actual lat and lon values from the work done in _gmap_views_find_coords_ids
  208. */
  209. function _gmap_views_get_lat_long_from_ids($entry, $ids) {
  210. // during the discovery phase, a module registered that it could turn this entry into a lat-lon array
  211. if ($ids['module']) {
  212. $ids['entry'] = $entry;
  213. return module_invoke($ids['module']['module'], 'gmap_views_handle_field', 'process', $ids);
  214. }
  215. // standard stuff, we can handle it
  216. return array('lat' => $entry->{$ids['lat']}, 'lon' => $entry->{$ids['lon']});
  217. }
  218. /**
  219. * Implementation of hook_views_query_alter().
  220. * We need to add in the node type so we can determine markers.
  221. */
  222. function gmap_views_query_alter(&$query, &$view, $summary, $level) {
  223. if (($view->page && $view->page_type == 'gmap') || ($view->block && $view->block_type == 'gmap')) {
  224. $query->add_field('type', 'node', 'gmap_node_type');
  225. if (module_exists('gmap_taxonomy')) {
  226. $query->ensure_table('gmap_taxonomy_node');
  227. $query->add_field('marker', 'gmap_taxonomy_node', 'gmap_taxonomy_marker');
  228. }
  229. }
  230. }