1 | <?php // $Id: geocode.module,v 1.6 2009/12/21 17:34:43 vauxia Exp $ |
---|
2 | |
---|
3 | /** |
---|
4 | * The Geocode API call. |
---|
5 | */ |
---|
6 | function geocode($handler, $input, $return = 'point', $options = array()) { |
---|
7 | static $handlers = array(); |
---|
8 | |
---|
9 | if (!isset($handlers[$handler])) { |
---|
10 | $info = geocode_handler_info(); |
---|
11 | if ($h = $info[$handler]) { |
---|
12 | // Load the geocoder's file. |
---|
13 | $path = (isset($h['file path'])) ? $h['file path'] .'/' : ''; |
---|
14 | require_once $path . $h['file']; |
---|
15 | |
---|
16 | // Instantiate a class for it. |
---|
17 | $handlers[$handler] = New $handler($options); |
---|
18 | } |
---|
19 | } |
---|
20 | |
---|
21 | if (!$handler = $handlers[$handler]) return FALSE; |
---|
22 | |
---|
23 | if ($handler->geocode($input, $options)) { |
---|
24 | list ($type, $item) = explode(':', $return); |
---|
25 | return $handler->get_result($type, $item); |
---|
26 | } |
---|
27 | } |
---|
28 | |
---|
29 | /** |
---|
30 | * Return a list of all handlers that might geocode something for you. |
---|
31 | */ |
---|
32 | function geocode_handler_info($field_type = NULL, $return_type = NULL) { |
---|
33 | static $handlers; |
---|
34 | if (!$handlers) { |
---|
35 | module_load_include('inc', 'geocode', 'includes/geocode'); |
---|
36 | $handlers = module_invoke_all('geocode_handler_info'); |
---|
37 | drupal_alter('geocode_handlers', $handlers); |
---|
38 | } |
---|
39 | $return = $handlers; |
---|
40 | |
---|
41 | if ($field_type) { |
---|
42 | foreach($return as $i => $handler) { |
---|
43 | if (!in_array($field_type, $handler['field types'])) { |
---|
44 | unset($return[$i]); |
---|
45 | } |
---|
46 | } |
---|
47 | } |
---|
48 | /* // TODO parse return types. |
---|
49 | if ($return_type) { |
---|
50 | list($group, $type) = explode(':', $return_type); |
---|
51 | foreach($return as $key => $items) { |
---|
52 | if ($key != |
---|
53 | if (!in_array($field_type, $handler['field types'])) { |
---|
54 | unset($return[$i]); |
---|
55 | } |
---|
56 | } |
---|
57 | } |
---|
58 | */ |
---|
59 | return $return; |
---|
60 | } |
---|
61 | |
---|
62 | /** |
---|
63 | * Implementation of our own hook_geocode_handler_info(). |
---|
64 | */ |
---|
65 | function geocode_geocode_handler_info() { |
---|
66 | $handlers = array(); |
---|
67 | |
---|
68 | // A default geocoding handler. |
---|
69 | $handlers['geocode_google'] = array( |
---|
70 | 'label' => t('Google API'), |
---|
71 | 'callback' => 'geocode_handler_google', |
---|
72 | 'module' => 'geocode', |
---|
73 | 'file' => 'geocode.inc', |
---|
74 | 'file path' => drupal_get_path('module', 'geocode') .'/includes', |
---|
75 | 'field types' => array('postal_field', 'postal', 'text'), |
---|
76 | 'element types' => array('postal', 'textfield', 'textarea'), |
---|
77 | 'return types' => array( |
---|
78 | 'geo' => array('point'), |
---|
79 | 'postal' => array('postal'), |
---|
80 | 'text' => array('country', 'city', 'state', 'zip'), |
---|
81 | ), |
---|
82 | ); |
---|
83 | |
---|
84 | // Based on availablilty, include handlers that leverage installed modules. |
---|
85 | // This is for some out-of-the-box interoperability, but should be supplanted |
---|
86 | // by modules implementing hook_geocode_hander_info() on their own. |
---|
87 | $dir = drupal_get_path('module', 'geocode') . '/includes/modules/'; |
---|
88 | foreach (file_scan_directory($dir, '\.inc$') as $file) { |
---|
89 | if (module_exists($module = $file->name)) { |
---|
90 | $func = $module . '_geocode_handler_info'; |
---|
91 | |
---|
92 | // Call hook_geocode_handler_info() if the module doesn't account for it. |
---|
93 | if (!function_exists($func) && !function_exists($func .'_alter')) { |
---|
94 | require $dir . $module .'.inc'; |
---|
95 | $handlers = array_merge($handlers, $func()); |
---|
96 | } |
---|
97 | } |
---|
98 | } |
---|
99 | |
---|
100 | return $handlers; |
---|
101 | } |
---|
102 | |
---|
103 | /** |
---|
104 | * Implementation of hook_gis_input_info(). |
---|
105 | */ |
---|
106 | function geocode_gis_input_info($gis_type = NULL) { |
---|
107 | $inputs = array(); |
---|
108 | foreach (geocode_handler_info() as $handler => $info) { |
---|
109 | // Only deal with handlers that attach to a form element. |
---|
110 | if (!isset($info['element types']) || !isset($info['return types']['geo'])) { |
---|
111 | continue; |
---|
112 | } |
---|
113 | |
---|
114 | foreach ($info['element types'] as $type) { |
---|
115 | $inputs[$handler .'_'. $type] = array( |
---|
116 | 'label' => $info['label'] .': '. $type, |
---|
117 | 'gis input' => 'wkt', // TODO this is for compatibility with GIS tools. Perhaps there's a way to define what we expect? |
---|
118 | 'gis types' => $info['return types']['geo'], |
---|
119 | 'gis callback' => 'geocode_convert', |
---|
120 | 'handler' => $handler, |
---|
121 | 'element' => array( |
---|
122 | '#type' => $type, |
---|
123 | ), |
---|
124 | ); |
---|
125 | } |
---|
126 | } |
---|
127 | return $inputs; |
---|
128 | } |
---|
129 | |
---|
130 | // TODO this should be deprecated completely. Currently proof of concept. |
---|
131 | function geocode_convert($input, $value, $return_format) { |
---|
132 | $handler = $input['handler']; |
---|
133 | return geocode($handler, $value, $return_format); |
---|
134 | } |
---|