geocoder.module 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246
  1. <?php
  2. /**
  3. * @file
  4. * Module file for geocoder module.
  5. */
  6. include_once('geocoder.widget.inc');
  7. include_once('geocoder.services.inc');
  8. /**
  9. * The Geocode API call.
  10. * @example:
  11. * geocoder('google','4925 Gair Ave, Terrace, BC');
  12. * geocoder('google','New York City',array('geometry_type' => 'bounds'));
  13. */
  14. function geocoder($handler, $data, $options = array()) {
  15. ctools_include('plugins');
  16. $processor = ctools_get_plugins('geocoder', 'geocoder_handler', $handler);
  17. return call_user_func($processor['callback'], $data, $options);
  18. }
  19. /**
  20. * Implements hook_menu().
  21. */
  22. function geocoder_menu() {
  23. // Admin settings for the site.
  24. $items['admin/config/content/geocoder'] = array(
  25. 'title' => 'Geocoder settings',
  26. 'description' => 'Configuration for API keys.',
  27. 'page callback' => 'drupal_get_form',
  28. 'page arguments' => array('geocoder_admin_settings'),
  29. 'file' => 'geocoder.admin.inc',
  30. 'access arguments' => array('administer site configuration'),
  31. 'type' => MENU_NORMAL_ITEM, // optional
  32. );
  33. $items['geocoder/service/%'] = array(
  34. 'title' => 'AJAX / AJAJ geocoding service',
  35. 'description' => 'Provides basic callback for geocoding using JavaScript',
  36. 'page callback' => 'geocoder_service_callback',
  37. 'page arguments' => array(2),
  38. 'type' => MENU_CALLBACK,
  39. 'access arguments' => array(arg(2)),
  40. 'access callback' => 'geocoder_service_check_perms',
  41. );
  42. return $items;
  43. }
  44. /**
  45. * Geocoder Handler Information
  46. *
  47. * Return a list of all handlers that might geocode something for you.
  48. * Optionally you may pass a field-type and get back a list of
  49. * handlers that are compatible with that field.
  50. */
  51. function geocoder_handler_info($field_type = NULL) {
  52. ctools_include('plugins');
  53. static $handlers;
  54. if (!$handlers) {
  55. $handlers = ctools_get_plugins('geocoder', 'geocoder_handler');
  56. }
  57. if ($field_type) {
  58. $field_handlers = $handlers;
  59. foreach ($field_handlers as $i => $handler) {
  60. if (!isset($handler['field_types']) || !in_array($field_type, $handler['field_types'])) {
  61. unset($field_handlers[$i]);
  62. }
  63. }
  64. return $field_handlers;
  65. }
  66. return $handlers;
  67. }
  68. /**
  69. * Fetch geocoder handler
  70. *
  71. * Given a name, fetch the full handler definition
  72. */
  73. function geocoder_get_handler($handler_name) {
  74. $handlers = geocoder_handler_info();
  75. if (isset($handlers[$handler_name])) {
  76. return $handlers[$handler_name];
  77. }
  78. else return FALSE;
  79. }
  80. /**
  81. * Get supported field types
  82. *
  83. * Get a list of supported field types along with the processors that support them
  84. */
  85. function geocoder_supported_field_types() {
  86. $supported = array();
  87. $processors = geocoder_handler_info();
  88. foreach ($processors as $processor) {
  89. if (isset($processor['field_types'])) {
  90. foreach ($processor['field_types'] as $field_type) {
  91. $supported[$field_type][] = $processor['name'];
  92. }
  93. }
  94. }
  95. return $supported;
  96. }
  97. /**
  98. * Implementation of hook_ctools_plugin_api().
  99. */
  100. function geocoder_ctools_plugin_api() {
  101. return array('version' => 1);
  102. }
  103. /**
  104. * Implementation of hook_ctools_plugin_dierctory() to let the system know
  105. * we implement plugins.
  106. */
  107. function geocoder_ctools_plugin_directory($module, $plugin) {
  108. return 'plugins/' . $plugin;
  109. }
  110. /**
  111. * Implements hook_ctools_plugin_type
  112. */
  113. function geocoder_ctools_plugin_type() {
  114. return array(
  115. 'geocoder_handler' => array(),
  116. );
  117. }
  118. // These functions have to do with providing AJAX / AHAH
  119. // service functionality so that users can make use of
  120. // geocoder interactively via JavaScript.
  121. /**
  122. * Implements hook_permission().
  123. *
  124. * We define permissions for accessing geocoder over AJAX / services.
  125. * There is one global permission which gives access to everything,
  126. * and one permission per handler. The site-administrator can therefore
  127. * fine tune which handlers are accessible. Note that to use AJAX with
  128. * geocoder these permissions need to be set.
  129. */
  130. function geocoder_permission() {
  131. $handler_info = geocoder_handler_info();
  132. $perms = array(
  133. 'geocoder_service_all_handlers' => array(
  134. 'title' => t('Can use all Geocoder handlers through AJAX / service'),
  135. ),
  136. );
  137. foreach ($handler_info as $name => $handler) {
  138. $perms['geocoder_service_handler_' . $name] = array(
  139. 'title' => t('Can geocode using @handler through AJAX / service', array('@handler' => $handler['title'])),
  140. );
  141. }
  142. return $perms;
  143. }
  144. /**
  145. * Geocoder service check permissions
  146. *
  147. * Given a handler, check to see if the user has
  148. * permission to execute it via AJAX / services
  149. */
  150. function geocoder_service_check_perms($handler) {
  151. return (user_access('geocoder_service_all_handlers') || user_access('geocoder_service_handler_' . $handler));
  152. }
  153. /**
  154. * Page callback for AJAX / Geocoder service
  155. *
  156. * This service can be accessed at /geocoder/service/<handler>
  157. * and takes the query-parameter "data". Optinally a "output"
  158. * paramater may also be passed. "output" corresponds to
  159. * geoPHP output formats.
  160. *
  161. * Some examples:
  162. * /geocoder/service/google?data=4925 Gair Ave, Terrace, BC
  163. * /geocoder/service/wkt?data=POINT(10 10)
  164. * /geocoder/service/yahoo?data=94112&output=wkt
  165. */
  166. function geocoder_service_callback($handler) {
  167. if (!isset($_GET['data'])) {
  168. throw new Exception(t('No data parameter found'));
  169. exit();
  170. }
  171. $format = isset($_GET['output']) ? $_GET['output'] : 'json';
  172. geophp_load();
  173. geocoder_service_check_request($handler, $format);
  174. $geom = geocoder($handler, $_GET['data']);
  175. header('Content-Type: ' . geocoder_service_get_content_type($format));
  176. print $geom->out($format);
  177. exit();
  178. }
  179. /**
  180. * Get Content-Type for an output format
  181. *
  182. * Given an output format, this helper function passes
  183. * a compatible HTTP content-type to be placed in the
  184. * header.
  185. */
  186. function geocoder_service_get_content_type($format) {
  187. $types = array(
  188. 'json' => 'application/json',
  189. 'kml' => 'application/xml',
  190. 'georss' => 'application/xml',
  191. 'gpx' => 'application/xml',
  192. 'wkt' => 'text/plain',
  193. 'wkb' => 'text/plain',
  194. 'google_geocode' => 'text/plain',
  195. );
  196. return $types[$format];
  197. }
  198. /**
  199. * Geocoder Service Check Request
  200. *
  201. * Check to make sure the request to the service is valid. This
  202. * checks to make sure the handler and the format exists, and
  203. * also checks permission
  204. */
  205. function geocoder_service_check_request($handler, $format, $check_ac = TRUE) {
  206. if (!geocoder_get_handler($handler)) {
  207. drupal_set_message(t('Could not find handler @handler', array('@handler' => $handler)), 'error');
  208. drupal_not_found();
  209. exit();
  210. }
  211. if (($format && $format != 'default') && !in_array($format, array_keys(geoPHP::getAdapterMap()))) {
  212. throw new Exception(t('Could not find output-format @format', array('@format' => $format)), 'error');
  213. exit();
  214. }
  215. if (!geocoder_service_check_perms($handler)) {
  216. drupal_access_denied();
  217. exit();
  218. }
  219. }