You are here

google_map_field.module in Google Map Field 7

Same filename and directory in other branches
  1. 8 google_map_field.module
  2. 7.2 google_map_field.module

This file defines all the necessary hooks and functions to create a Google Map Field field type and also a WYSIWYG editor plugin for inserting maps directly into filtered content.

File

google_map_field.module
View source
<?php

/**
 * @file
 * This file defines all the necessary hooks and functions to create
 * a Google Map Field field type and also a WYSIWYG editor plugin
 * for inserting maps directly into filtered content.
 */

/**
 * Implements hook_help().
 */
function google_map_field_help($path, $arg) {
  $output = '';
  switch ($path) {
    case 'admin/help#google_map_field':
      $output = t('Add Google Map type fields to content types, or enable an inline map token generator.');
      if (module_exists('wysiwyg')) {
        $url = l(t('Goto WYSIWYG profiles list'), 'admin/config/content/wysiwyg');
        $text = t('Edit your WYSIWYG profiles to enable the Google Map Field Token Genertor (under buttons and plugins).');
        $output .= '<p>' . $text . '</p><p>' . $url . '</p>';
      }
  }
  return $output;
}

/**
 * Implements hook_init().
 */
function google_map_field_init() {
  google_map_field_add_maps_api();
  drupal_add_js(drupal_get_path('module', 'google_map_field') . '/js/google_map_field_node_display.js', 'file');
  if (module_exists('wysiwyg')) {
    drupal_add_js(drupal_get_path('module', 'google_map_field') . '/js/google_map_field_edit_form.js', 'file');
    drupal_add_css(drupal_get_path('module', 'google_map_field') . '/wysiwyg_plugins/gmf_tokenbuilder/css/gmf_tokenbuilder.css');
    drupal_add_library('system', 'ui.dialog');
    drupal_add_library('system', 'ui.draggable');
  }
}

/**
 * Implements hook_menu().
 */
function google_map_field_menu() {
  $items = array();
  $items['admin/config/google-map-field-apikey'] = array(
    'title' => 'Google Map Field API Key',
    'description' => 'Set your Google Maps API key.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'google_map_field_apikey_settings_form',
    ),
    'file' => 'includes/google_map_field.admin.inc',
    'access arguments' => array(
      'access administration pages',
    ),
  );
  $items['google-map-field/token-builder'] = array(
    'access arguments' => array(
      'access content',
    ),
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'google_map_field_tokenbuilder_form',
    ),
    'type' => MENU_CALLBACK,
  );
  return $items;
}

/**
 * Implements hook_field_info().
 */
function google_map_field_field_info() {
  return array(
    'google_map_field' => array(
      'label' => t('Google Map Field'),
      'description' => t('This field stores and renders Google Maps.'),
      'instance_settings' => array(
        'cardinality' => 1,
      ),
      'default_widget' => 'google_map_field_widget',
      'default_formatter' => 'google_map_field_formatter_default',
    ),
  );
}

/**
 * Implements hook_field_widget_info().
 */
function google_map_field_field_widget_info() {
  return array(
    'google_map_field_widget' => array(
      'label' => t('Map'),
      'field types' => array(
        'google_map_field',
      ),
    ),
  );
}

/**
 * Implements hook_field_formatter_info().
 */
function google_map_field_field_formatter_info() {
  $formats = array(
    'google_map_field_formatter_default' => array(
      'label' => t('Map'),
      'description' => t('Default display for Google map field.'),
      'field types' => array(
        'google_map_field',
      ),
    ),
    'google_map_field_formatter_wkt' => array(
      'label' => t('WKT'),
      'description' => t('Use WKT format to display the google maps point info'),
      'field types' => array(
        'google_map_field',
      ),
    ),
  );
  return $formats;
}

/**
 * Implements hook_field_widget_error().
 */
function google_map_field_field_widget_error($element, $error, $form, &$form_state) {
  form_error($element, $error['message']);
}

/**
 * Implements hook_field_is_empty().
 */
function google_map_field_field_is_empty($item, $field) {
  if (empty($item['lat']) || empty($item['lon'])) {
    return TRUE;
  }
  return FALSE;
}

/**
 * Implements hook_field_formatter_view().
 */
function google_map_field_field_formatter_view($object_type, $object, $field, $instance, $langcode, $items, $display) {
  drupal_add_css(drupal_get_path('module', 'google_map_field') . '/css/google_map_field.css');
  $element = array();
  switch ($display['type']) {
    case 'google_map_field_formatter_wkt':
      foreach ($items as $delta => $item) {
        $element[$delta] = array(
          '#markup' => 'POINT(' . $item['lon'] . ' ' . $item['lat'] . ')',
        );
      }
      break;
    case 'google_map_field_formatter_default':
      foreach ($items as $delta => $item) {
        $element[$delta] = google_map_field_format_field($item, $delta, $display);
      }
      break;
  }
  return $element;
}

/**
 * This function formats the google map field for display,
 * called by google_map_field_field_formatter_view().
 */
function google_map_field_format_field($item, $delta, $display) {
  $map_id = uniqid();

  // Get the map details and place in an array to pass to Drupal.settings.
  $settings = array(
    'gmf_node_display' => array(
      'google_map_field_' . $map_id => array(
        'lat' => $item['lat'],
        'lon' => $item['lon'],
        'zoom' => $item['zoom'],
      ),
    ),
  );
  $element = array(
    '#type' => 'container',
    '#attributes' => array(
      'class' => array(
        'field-item',
      ),
    ),
  );
  $element['google_map_field'] = array(
    'item' => array(
      '#type' => 'container',
      '#attributes' => array(
        'class' => array(
          'field-item',
        ),
      ),
      'text' => array(
        '#markup' => theme('google_map_field', array(
          'name' => check_plain($item['name']),
          'map_id' => $map_id,
        )),
      ),
    ),
  );
  drupal_add_js($settings, 'setting');
  return $element;
}

/**
 * Implements hook_field_widget_form().
 */
function google_map_field_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
  $fname = str_replace('_', '-', $element['#field_name']);
  $element['#title'] = t('Google Map Field Settings');
  $element['#description'] = '<p>' . t('To set a location for the map, use the controls to zoom in or out and drag the map to find the correct area. Once you have found the correct location click that point to set the map.') . '</p>';
  $element += array(
    '#type' => 'fieldset',
    '#tree' => TRUE,
    '#collapsible' => TRUE,
    '#collapsed' => FALSE,
    '#after_build' => array(
      'google_map_field_after_build',
    ),
    '#fname' => $fname,
  );
  $element['fname'] = array(
    '#type' => 'hidden',
    '#value' => $fname,
  );
  $element['name'] = array(
    '#type' => 'textfield',
    '#title' => t('Map Name'),
    '#default_value' => isset($items[$delta]['name']) ? $items[$delta]['name'] : NULL,
    '#prefix' => '<div class="clearfix"><div class="google_map_field_left30pc">',
  );
  $element['lat'] = array(
    '#type' => 'textfield',
    '#title' => t('Latitude'),
    '#required' => $instance['required'],
    '#element_validate' => array(
      'google_map_field_latlon_validate',
    ),
    '#default_value' => isset($items[$delta]['lat']) ? $items[$delta]['lat'] : NULL,
  );
  $element['lon'] = array(
    '#type' => 'textfield',
    '#title' => t('Longitude'),
    '#required' => $instance['required'],
    '#element_validate' => array(
      'google_map_field_latlon_validate',
    ),
    '#default_value' => isset($items[$delta]['lon']) ? $items[$delta]['lon'] : NULL,
  );
  $element['zoom'] = array(
    '#type' => 'textfield',
    '#title' => t('Zoom'),
    '#default_value' => isset($items[$delta]['zoom']) ? $items[$delta]['zoom'] : 9,
    '#attributes' => array(
      'readonly' => 'readonly',
    ),
  );
  $element['center_on'] = array(
    '#type' => 'textfield',
    '#title' => t('Center On'),
    '#description' => t('To center the map on an approximate location, enter the location in the box above, e.g. "London, UK" or "1 Southwark Street, London, UK" and click \'center\''),
  );
  $element['do_center'] = array(
    '#type' => 'button',
    '#value' => t('center'),
    '#attributes' => array(
      'onclick' => 'return google_map_field_doCenter();',
    ),
    '#suffix' => '</div>',
  );
  $element['map'] = array(
    '#markup' => theme('google_map_field_map_picker'),
    '#prefix' => '<div class="google_map_field_left65pc">',
    '#suffix' => '</div></div>',
  );
  return $element;
}

/**
 *  Custom validation function for latitude/longitude fields.
 */
function google_map_field_latlon_validate($element, $form, &$form_state) {
  if (!is_numeric($element['#value']) && !empty($element['#value'])) {
    $field = implode('][', $element['#array_parents']);
    form_set_error($field, t('Invalid value - @title', array(
      '@title' => $element['#title'],
    )));
  }
}

/**
 * Implements hook_filter_info().
 */
function google_map_field_filter_info() {
  $filters['google_map_field_token'] = array(
    'title' => t('Google Map Field'),
    'description' => t('Use tokens to insert Google Map Fields.'),
    'process callback' => 'google_map_field_filter_process',
    'cache' => FALSE,
  );
  return $filters;
}

/**
 *  Process callback for hook_filter_info().
 */
function google_map_field_filter_process($text, $filter, $format) {
  $out = $text;
  $matches = array();
  preg_match_all('/\\[gmf\\:([^\\]]*)\\]/', $text, $matches);
  $i = 0;
  while (isset($matches[0][$i])) {
    $old = '/' . str_replace(']', '\\]', str_replace('[', '\\[', $matches[0][$i])) . '/';
    $new = $matches[1][$i] . ';';
    $out = preg_replace($old, $new, $out, 1);
    $i++;
  }
  preg_match_all('/lat([^\\]]*)\\;/', $out, $matches);
  $i = 0;
  $delta = 1000;

  //google_map_field_add_maps_api();
  $maps = array();
  while (isset($matches[1][$i])) {
    $match = str_replace(';', '', $matches[0][$i]);
    $settings = explode(',', $match);
    $map_settings = array();
    foreach ($settings as $setting) {
      $offset = strpos($setting, '=');
      if ($offset !== FALSE) {
        $key = trim(substr($setting, 0, $offset));
        $val = trim(substr($setting, $offset + 1));
        $map_settings[$key] = $val;
      }
    }
    $maps[$i] = $map_settings;

    //$replace = str_replace(']', '\]/', str_replace('[', '/\\[', $matches[0][$i]));
    $replace = $matches[0][$i];
    $settings = array(
      'delta' => $delta,
      'width' => $map_settings['width'],
      'height' => $map_settings['height'],
    );
    $replacement = theme('google_map_field_map_token', $settings);
    $out = preg_replace('/' . $matches[0][$i] . '/', $replacement, $out, 1);
    $delta++;
    $i++;
  }
  $map_collection = array(
    'gmf_token_maps' => $maps,
  );
  drupal_add_js(drupal_get_path('module', 'google_map_field') . '/js/google_map_field_token_maps.js');
  drupal_add_js($map_collection, 'setting');
  return $out;
}

/**
 * Implements hook_wysiwyg_include_directory().
 */
function google_map_field_wysiwyg_include_directory($type) {
  switch ($type) {
    case 'plugins':
      return 'wysiwyg_plugins';
      break;
  }
}

/**
 *  Function to add necessary JS and CSS after form has built.
 */
function google_map_field_after_build($form, &$form_state) {

  //google_map_field_add_maps_api();
  drupal_add_js(drupal_get_path('module', 'google_map_field') . '/js/google_map_field_edit_form.js', 'file');
  drupal_add_js(drupal_get_path('module', 'google_map_field') . '/js/google_map_field_widget_form.js', 'file');
  drupal_add_css(drupal_get_path('module', 'google_map_field') . '/wysiwyg_plugins/gmf_tokenbuilder/css/gmf_tokenbuilder.css');
  drupal_add_css(drupal_get_path('module', 'google_map_field') . '/css/google_map_field.css');
  drupal_add_library('system', 'ui.dialog');
  drupal_add_library('system', 'ui.draggable');

  // Build the inline JS to build the map.
  $settings = array(
    'gmf_widget_form' => array(
      'lat' => is_numeric($form['lat']['#value']) ? $form['lat']['#value'] : 51.51906840672028,
      'lon' => is_numeric($form['lon']['#value']) ? $form['lon']['#value'] : -0.11661621093753638,
      'zoom' => is_numeric($form['zoom']['#value']) ? $form['zoom']['#value'] : 9,
      'fname' => $form['#fname'],
    ),
  );
  drupal_add_js($settings, 'setting');
  return $form;
}

/**
 *  Form builder for the google map field token builder.
 */
function google_map_field_tokenbuilder_form($form, &$form_state) {
  drupal_set_title(t('Google Map Field Token Builder'));
  $form = array();
  $form['token_builder']['map'] = array(
    '#markup' => theme('google_map_field_map_selector'),
    '#prefix' => '<div class="google-map-field-tokenbuilder clearfix"><div class="google-map-field-tokenbuilder-map">',
    '#suffix' => '</div>',
  );
  $form['token_builder']['width'] = array(
    '#type' => 'textfield',
    '#title' => t('Width'),
    '#size' => 15,
    '#default_value' => '300',
    '#attributes' => array(
      'onkeyup' => 'return buildToken();',
    ),
    '#prefix' => '<div class="google-map-field-tokenbuilder-fields">',
  );
  $form['token_builder']['height'] = array(
    '#type' => 'textfield',
    '#title' => t('Height'),
    '#size' => 15,
    '#default_value' => '250',
    '#attributes' => array(
      'onkeyup' => 'return buildToken();',
    ),
  );
  $form['token_builder']['zoom'] = array(
    '#type' => 'textfield',
    '#title' => t('Zoom'),
    '#size' => 15,
    '#default_value' => '9',
    '#attributes' => array(
      'readonly' => 'readonly',
    ),
    '#suffix' => '</div></div>',
  );
  $form['token_builder']['token'] = array(
    '#type' => 'hidden',
    '#attributes' => array(
      'id' => 'edit-token',
    ),
    '#default_value' => 'lat=51.0,lon=0.12,width=300,height=250,zoom=9',
  );
  $form['token_builder']['center_on'] = array(
    '#type' => 'textfield',
    '#title' => t('Center On'),
    '#description' => t('To center the map on an approximate location, enter the location in the box above, e.g. "London, UK" or "1 Southwark Street, London, UK" and click \'center\''),
  );
  $form['token_builder']['do_center'] = array(
    '#type' => 'button',
    '#value' => t('center'),
    '#attributes' => array(
      'onclick' => 'return google_map_field_doCenterPopup();',
    ),
  );
  return $form;
}

/**
 * Implements hook_theme().
 */
function google_map_field_theme($existing, $type, $theme, $path) {
  if ($type == 'module') {
    return array(
      'google_map_field' => array(
        'variables' => array(
          'name' => NULL,
          'map_id' => NULL,
        ),
        'template' => 'google-map-field',
        'path' => drupal_get_path('module', 'google_map_field') . '/theme',
      ),
      'google_map_field_map_selector' => array(
        'render_element' => 'element',
      ),
      'google_map_field_map_picker' => array(
        'render_element' => 'element',
      ),
      'google_map_field_map_token' => array(
        'render_element' => 'element',
        'variables' => array(
          'delta' => NULL,
          'width' => NULL,
          'height' => NULL,
        ),
      ),
    );
  }
  return array();
}

/**
 * Implements form_field_ui_field_edit_form_alter().
 */
function google_map_field_form_field_ui_field_edit_form_alter(&$form, &$form_state) {
  if ($form['#field']['type'] == 'google_map_field') {
    drupal_add_css(drupal_get_path('module', 'google_map_field') . '/css/google_map_field.css');
    $form['field']['cardinality']['#default_value'] = 1;
    $form['field']['#access'] = FALSE;
  }
}

/**
 *  Theme function to return map selector div on token builder overlay.
 */
function theme_google_map_field_map_selector($variables) {
  return '<div id="google_map_field_selector"></div>';
}

/**
 *  Theme function to return map picker div on node edit form.
 */
function theme_google_map_field_map_picker($variables) {
  return '<div id="google_map_picker"></div>';
}

/**
 * Theme function to return map div for tokenised maps.
 */
function theme_google_map_field_map_token($variables) {
  return '
    <div id="inline_google_map_field_' . $variables['delta'] . '" class="inline-google-map-field" style="width: ' . $variables['width'] . 'px; height: ' . $variables['height'] . 'px;"></div>
  ';
}

/**
 * Helper function to add the Google Maps API.
 */
function google_map_field_add_maps_api() {
  if (variable_get('google_map_field_apikey', '') != '') {
    $element = array(
      '#type' => 'markup',
      '#markup' => '<script type="text/javascript" src="http://maps.googleapis.com/maps/api/js?sensor=false&key=' . variable_get('google_map_field_apikey', '') . '"></script>',
    );
    drupal_add_html_head($element, 'google_maps_api');
  }
  else {
    drupal_add_js('http://maps.googleapis.com/maps/api/js?sensor=false', 'external');
  }
}

Functions

Namesort descending Description
google_map_field_add_maps_api Helper function to add the Google Maps API.
google_map_field_after_build Function to add necessary JS and CSS after form has built.
google_map_field_field_formatter_info Implements hook_field_formatter_info().
google_map_field_field_formatter_view Implements hook_field_formatter_view().
google_map_field_field_info Implements hook_field_info().
google_map_field_field_is_empty Implements hook_field_is_empty().
google_map_field_field_widget_error Implements hook_field_widget_error().
google_map_field_field_widget_form Implements hook_field_widget_form().
google_map_field_field_widget_info Implements hook_field_widget_info().
google_map_field_filter_info Implements hook_filter_info().
google_map_field_filter_process Process callback for hook_filter_info().
google_map_field_format_field This function formats the google map field for display, called by google_map_field_field_formatter_view().
google_map_field_form_field_ui_field_edit_form_alter Implements form_field_ui_field_edit_form_alter().
google_map_field_help Implements hook_help().
google_map_field_init Implements hook_init().
google_map_field_latlon_validate Custom validation function for latitude/longitude fields.
google_map_field_menu Implements hook_menu().
google_map_field_theme Implements hook_theme().
google_map_field_tokenbuilder_form Form builder for the google map field token builder.
google_map_field_wysiwyg_include_directory Implements hook_wysiwyg_include_directory().
theme_google_map_field_map_picker Theme function to return map picker div on node edit form.
theme_google_map_field_map_selector Theme function to return map selector div on token builder overlay.
theme_google_map_field_map_token Theme function to return map div for tokenised maps.