View source  
  <?php
include_once 'geocoder.widget.inc';
include_once 'geocoder.services.inc';
define('GEOCODER_GOOGLE_AUTH_NONE', 1);
define('GEOCODER_GOOGLE_AUTH_KEY', 2);
define('GEOCODER_GOOGLE_AUTH_WORK', 3);
function geocoder_reverse($handler, $lat, $long, $options = array(), $cache_type = 2, $cache_reset = FALSE) {
  ctools_include('plugins');
  static $static_cache_reverse = array();
  if ($cache_reset) {
    $static_cache_reverse = array();
  }
  if ($cache_type) {
    $cache_id = $handler . '_' . md5(serialize(array(
      $lat,
      $long,
      $options,
    )));
    if (!empty($static_cache_reverse[$cache_id])) {
      return $static_cache_reverse[$cache_id];
    }
  }
  $processor = ctools_get_plugins('geocoder', 'geocoder_reverse_handler', $handler);
  $address = call_user_func($processor['callback'], $lat, $long, $options);
  if ($cache_type) {
    $static_cache_reverse[$cache_id] = $address;
  }
  return $address;
}
function geocoder($handler, $data, $options = array(), $cache_type = 'DEPRECATED', $cache_reset = FALSE) {
  ctools_include('plugins');
  $processor = ctools_get_plugins('geocoder', 'geocoder_handler', $handler);
  if (!$processor) {
    return NULL;
  }
  
  $geometry = $cache_reset ? NULL : geocoder_cache_get($handler, $data, $options);
  
  if ($geometry === NULL) {
    try {
      
      geocoder_get_handler($handler);
      $geometry = call_user_func($processor['callback'], $data, $options);
    } catch (Exception $e) {
      watchdog_exception('geocoder', $e);
      return NULL;
    }
    
    geocoder_cache_set($geometry, $handler, $data, $options);
  }
  if (!$geometry && variable_get('geocoder_log_empty_results', FALSE)) {
    watchdog('geocoder', t('No results for geocoding @data', array(
      '@data' => $data,
    )));
  }
  return $geometry;
}
function geocoder_menu() {
  
  $items['admin/config/content/geocoder'] = array(
    'title' => 'Geocoder settings',
    'description' => 'Configuration for API keys and other global settings.',
    'page callback' => 'drupal_get_form',
    'page arguments' => array(
      'geocoder_admin_settings',
    ),
    'file' => 'geocoder.admin.inc',
    'access arguments' => array(
      'administer site configuration',
    ),
    
    'type' => MENU_DEFAULT_LOCAL_TASK,
  );
  $items['geocoder/service/%'] = array(
    'title' => 'AJAX / AJAJ geocoding service',
    'description' => 'Provides basic callback for geocoding using JavaScript',
    'page callback' => 'geocoder_service_callback',
    'page arguments' => array(
      2,
    ),
    'type' => MENU_CALLBACK,
    'access arguments' => array(
      arg(2),
    ),
    'access callback' => 'geocoder_service_check_perms',
  );
  return $items;
}
function geocoder_handler_info($field_type = NULL) {
  ctools_include('plugins');
  static $handlers;
  if (!$handlers) {
    $handlers = ctools_get_plugins('geocoder', 'geocoder_handler');
  }
  if ($field_type) {
    $field_handlers = $handlers;
    foreach ($field_handlers as $i => $handler) {
      if (!isset($handler['field_types']) || !in_array($field_type, $handler['field_types'], TRUE)) {
        unset($field_handlers[$i]);
      }
    }
    return $field_handlers;
  }
  return $handlers;
}
function geocoder_get_handler($handler_name) {
  $handlers = geocoder_handler_info();
  if (isset($handlers[$handler_name])) {
    require_once $handlers[$handler_name]['path'] . '/' . $handlers[$handler_name]['file'];
    return $handlers[$handler_name];
  }
  return FALSE;
}
function geocoder_supported_field_types() {
  $supported = array();
  $processors = geocoder_handler_info();
  foreach ($processors as $processor) {
    if (isset($processor['field_types'])) {
      foreach ($processor['field_types'] as $field_type) {
        $supported[$field_type][] = $processor['name'];
      }
    }
  }
  return $supported;
}
function geocoder_ctools_plugin_api() {
  return array(
    'version' => 1,
  );
}
function geocoder_ctools_plugin_directory($module, $plugin) {
  return 'plugins/' . $plugin;
}
function geocoder_ctools_plugin_type() {
  return array(
    'geocoder_handler' => array(
      'cache' => TRUE,
    ),
    'geocoder_reverse_handler' => array(),
  );
}
function geocoder_permission() {
  $handler_info = geocoder_handler_info();
  $perms = array(
    'geocoder_service_all_handlers' => array(
      'title' => t('Can use all Geocoder handlers through AJAX / service'),
    ),
  );
  foreach ($handler_info as $name => $handler) {
    $perms['geocoder_service_handler_' . $name] = array(
      'title' => t('Can geocode using @handler through AJAX / service', array(
        '@handler' => $handler['title'],
      )),
    );
  }
  return $perms;
}
function geocoder_service_check_perms($handler) {
  return user_access('geocoder_service_all_handlers') || user_access('geocoder_service_handler_' . $handler);
}
function geocoder_service_callback($handler) {
  if (!isset($_GET['data'])) {
    throw new Exception(t('No data parameter found'));
    exit;
  }
  $format = isset($_GET['output']) ? $_GET['output'] : 'json';
  geophp_load();
  geocoder_service_check_request($handler, $format);
  $geom = geocoder($handler, $_GET['data']);
  header('Content-Type: ' . geocoder_service_get_content_type($format));
  print $geom
    ->out($format);
  exit;
}
function geocoder_service_get_content_type($format) {
  $types = array(
    'json' => 'application/json',
    'kml' => 'application/xml',
    'georss' => 'application/xml',
    'gpx' => 'application/xml',
    'wkt' => 'text/plain',
    'wkb' => 'text/plain',
    'google_geocode' => 'text/plain',
  );
  return $types[$format];
}
function geocoder_service_check_request($handler, $format, $check_ac = TRUE) {
  if (!geocoder_get_handler($handler)) {
    drupal_set_message(t('Could not find handler @handler', array(
      '@handler' => $handler,
    )), 'error');
    drupal_not_found();
    exit;
  }
  if ($format && $format !== 'default' && !in_array($format, array_keys(geoPHP::getAdapterMap()), TRUE)) {
    throw new Exception(t('Could not find output-format @format', array(
      '@format' => $format,
    )), 'error');
    exit;
  }
  if (!geocoder_service_check_perms($handler)) {
    drupal_access_denied();
    exit;
  }
}
function _geocoder_cache_cid($data) {
  ksort($data);
  return sha1(serialize($data));
}
function geocoder_cache_get($handler, $data, $options) {
  $data = compact('handler', 'data', 'options');
  $cid = _geocoder_cache_cid($data);
  geophp_load();
  if ($cache = cache_get($cid, 'cache_geocoder')) {
    return $cache->data['geometry'];
  }
}
function geocoder_cache_set($geometry, $handler, $data, $options) {
  
  if (!$geometry && !variable_get('geocoder_cache_empty_results', TRUE)) {
    return;
  }
  
  $data = compact('handler', 'data', 'options');
  $cid = _geocoder_cache_cid($data);
  
  $data['geometry'] = $geometry ? $geometry : FALSE;
  cache_set($cid, $data, 'cache_geocoder', variable_get('geocoder_cache_ttl', CACHE_PERMANENT));
}
function geocoder_flush_caches() {
  return array(
    'cache_geocoder',
  );
}