'bounds')); */ function geocoder($handler, $data, $options = array(), $cache_type = 2, $cache_reset = FALSE) { ctools_include('plugins'); static $static_cache = array(); if ($cache_reset) { $static_cache = array(); } if ($cache_type) { $cache_id = $handler . '_' . md5(serialize(array($data, $options))); if (!empty($static_cache[$cache_id])) { return $static_cache[$cache_id]; } } $processor = ctools_get_plugins('geocoder', 'geocoder_handler', $handler); $geometry = call_user_func($processor['callback'], $data, $options); if ($cache_type) { $static_cache[$cache_id] = $geometry; } return $geometry; } /** * Implements hook_menu(). */ function geocoder_menu() { // Admin settings for the site. $items['admin/config/content/geocoder'] = array( 'title' => 'Geocoder settings', 'description' => 'Configuration for API keys.', 'page callback' => 'drupal_get_form', 'page arguments' => array('geocoder_admin_settings'), 'file' => 'geocoder.admin.inc', 'access arguments' => array('administer site configuration'), 'type' => MENU_NORMAL_ITEM, // optional ); $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; } /** * Geocoder Handler Information * * Return a list of all handlers that might geocode something for you. * Optionally you may pass a field-type and get back a list of * handlers that are compatible with that field. */ 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'])) { unset($field_handlers[$i]); } } return $field_handlers; } return $handlers; } /** * Fetch geocoder handler * * Given a name, fetch the full handler definition */ function geocoder_get_handler($handler_name) { $handlers = geocoder_handler_info(); if (isset($handlers[$handler_name])) { return $handlers[$handler_name]; } else return FALSE; } /** * Get supported field types * * Get a list of supported field types along with the processors that support them */ 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; } /** * Implementation of hook_ctools_plugin_api(). */ function geocoder_ctools_plugin_api() { return array('version' => 1); } /** * Implementation of hook_ctools_plugin_dierctory() to let the system know * we implement plugins. */ function geocoder_ctools_plugin_directory($module, $plugin) { return 'plugins/' . $plugin; } /** * Implements hook_ctools_plugin_type */ function geocoder_ctools_plugin_type() { return array( 'geocoder_handler' => array(), ); } // These functions have to do with providing AJAX / AHAH // service functionality so that users can make use of // geocoder interactively via JavaScript. /** * Implements hook_permission(). * * We define permissions for accessing geocoder over AJAX / services. * There is one global permission which gives access to everything, * and one permission per handler. The site-administrator can therefore * fine tune which handlers are accessible. Note that to use AJAX with * geocoder these permissions need to be set. */ 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; } /** * Geocoder service check permissions * * Given a handler, check to see if the user has * permission to execute it via AJAX / services */ function geocoder_service_check_perms($handler) { return (user_access('geocoder_service_all_handlers') || user_access('geocoder_service_handler_' . $handler)); } /** * Page callback for AJAX / Geocoder service * * This service can be accessed at /geocoder/service/ * and takes the query-parameter "data". Optinally a "output" * paramater may also be passed. "output" corresponds to * geoPHP output formats. * * Some examples: * /geocoder/service/google?data=4925 Gair Ave, Terrace, BC * /geocoder/service/wkt?data=POINT(10 10) * /geocoder/service/yahoo?data=94112&output=wkt */ 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(); } /** * Get Content-Type for an output format * * Given an output format, this helper function passes * a compatible HTTP content-type to be placed in the * header. */ 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]; } /** * Geocoder Service Check Request * * Check to make sure the request to the service is valid. This * checks to make sure the handler and the format exists, and * also checks permission */ 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()))) { 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(); } }