/[drupal]/contributions/modules/connect/connect_lookup.php
ViewVC logotype

Contents of /contributions/modules/connect/connect_lookup.php

Parent Directory Parent Directory | Revision Log Revision Log | View Revision Graph Revision Graph


Revision 1.2 - (show annotations) (download) (as text)
Fri Apr 3 16:13:28 2009 UTC (7 months, 3 weeks ago) by stevem
Branch: MAIN
CVS Tags: DRUPAL-5--2-0-BETA1, HEAD
Changes since 1.1: +355 -85 lines
File MIME type: text/x-php
many changes; moving source control to Drupal CVS from local SVN
1 <?php
2
3 /**
4 * interface function for returning lookup description or data
5 */
6 function connect_target_lookup(&$parent, &$child, $op = 'lookup', $type = '') {
7 $return = false;
8 if ($parent && $type) {
9 $lookup = connect_node_options( $parent->nid, $type.'_lookup_type' );
10 if ($lookup) {
11 eval('$return = '.$lookup.'($op, $parent, $child);');
12 }
13 }
14 return $return;
15 }
16
17
18 /*
19 * connect_lookup_NAME( $op = 'lookup', $child )
20 *
21 * @ param $op
22 * 'lookup' -> perform the lookup
23 * 'requires' -> get info to pass through via connect_action_hook function
24 * 'describe' -> returns a title to display on the node settings form
25 * 'cache' -> returns an array of descriptors for the cache table
26 *
27 * @ return
28 * if $op=='lookup': object( object->email object->name object->fax, etc )
29 * if $op=='requires' : array as per connect_action_* 'requires' op
30 * if $op=='describe' : string describing the function
31 * of $op=='cache' : array describing the connet_cache items this lookup can/may use
32 */
33
34
35
36 /*
37 * function to look up contact info for Ontario MPP -- basic lookup from Postal Code
38 *
39 * uses the OpenConcept Consulting web service at http://makethechange.ca/
40 * which requires a client key
41 *
42 */
43 function connect_lookup_mpp_ontario($op = 'lookup', &$parent, &$child) {
44 switch ($op) {
45 case 'describe' :
46 return 'Ontario MPP (postal code)';
47 break;
48
49 case 'cache' :
50 return array(
51 'EDID2MPP' => 'Federal riding to ontario MPP',
52 'pc2riding_provincial_ontario_ca' => 'Postal code to Ontario riding'
53 );
54 break;
55
56 case 'requires':
57 $return['variables'] = array(
58 //uses the same key as mp lookup
59 'makethechange_key' => array(
60 '#type' => 'textfield',
61 '#title' => 'Makethechange web service key',
62 '#default_value' => connect_node_options($parent->nid, 'makethechange_key'),
63 '#required' => TRUE,
64 ),
65
66 //uniquie cache for mpp
67 'mpp_ontario_lookup_cache' => array(
68 '#type' => 'radios',
69 '#title' => 'Cache the MPP lookup data?',
70 '#options' => array( 'no' => 'No', 'yes' => 'Yes'),
71 '#default_value' => connect_node_options($parent->nid, 'mpp_ontario_lookup_cache'),
72 '#required' => TRUE,
73 ),
74 );
75
76 $return['child'] = array(
77 //same postal code as mp lookup
78 'postal_code' => 'Postal code',
79
80 //unique edid for ontario mpp
81 'lookup_mp_data_edid_ontario' => 'Ontario Riding',
82 );
83 return $return;
84
85 //validate the postal code (same code as mp lookup)
86 case 'validate' :
87 $code = connect_value( 'postal_code', $parent, $child, 'child' );
88 if ( !connect_is_postalcode($code) ) {
89 form_set_error('', 'Please enter a valid postal code.');
90 }
91 break;
92
93 //this is the meat of the function looks up edid then looks up the email of the ontari mpp based on edid
94 case 'lookup':
95 $return = array();
96 $use_cache = (connect_node_options($parent->nid, 'mpp_ontario_lookup_cache') == 'yes');
97 $mtc_key = connect_node_options($parent->nid, 'makethechange_key');
98 $postalcode = connect_value('postal_code', $parent, $child, 'child');
99
100 //find the edid based on postal code (for ontario ridings)
101 $edid = _connect_get_riding($mtc_key, $postalcode, 'provincial', 'ontario', $use_cache);
102
103 if ($edid) {
104 // save the riding in the child node
105 connect_value('lookup_mp_data_edid_ontario', $parent, $child, 'child', $edid[0]['id']);
106
107 /* Danger! in rare cases there may be > 1 matches: this
108 * just grabs the first one; if this is a problem,
109 * use the CCK MPautocomplete version to allow users to select a riding
110 * or write a two-stage version of the participation form
111 */
112
113 //look up mp data
114 $mpp = _connect_get_ontario_MPP_by_EDID($mtc_key, $edid[0]['id'], $use_cache);
115 if (!empty($mpp)){
116 $return['name'] = $mpp->full_name;
117 $return['email'] = $mpp->email;
118 $return['fax'] = $mpp->fax;
119 //***there is no fax for mpp?***
120 }
121 else {
122 watchdog('connect', "connect_lookup_mpp_ontario: MPP not found for " . $edid[0][id]);
123 }
124 }
125 else {
126 watchdog('connect', "connect_lookup_mpp_ontario: EDID not found for $postalcode");
127 }
128
129 return $return;
130 break;
131
132 }
133 }
134
135 /*
136 * function to look up contact info for Canadian MP -- basic lookup from Postal Code
137 *
138 * uses the OpenConcept Consulting web service at http://makethechange.ca/
139 * which requires a client key
140 *
141 */
142 function connect_lookup_mp($op = 'lookup', &$parent, &$child) {
143 switch ($op) {
144 case 'describe' :
145 return 'Canadian MP (postal code)';
146 break;
147
148 case 'cache' :
149 return array(
150 'EDID2MP' => 'Federal riding to MP',
151 'pc2riding_federal_federal_ca' => 'Postal code to Federal riding'
152 );
153 break;
154
155 case 'requires':
156 $return['variables'] = array(
157 'makethechange_key' => array(
158 '#type' => 'textfield',
159 '#title' => 'Makethechange web service key',
160 '#default_value' => connect_node_options($parent->nid, 'makethechange_key'),
161 '#required' => TRUE,
162 ),
163 'mp_lookup_cache' => array(
164 '#type' => 'radios',
165 '#title' => 'Cache the lookup data?',
166 '#options' => array( 'no' => 'No', 'yes' => 'Yes'),
167 '#default_value' => connect_node_options($parent->nid, 'mp_lookup_cache'),
168 '#required' => TRUE,
169 ),
170 );
171
172 $return['child'] = array(
173 'postal_code' => 'Postal code',
174 'lookup_mp_data_edid' => 'Riding',
175 );
176 return $return;
177
178 case 'validate' :
179 $code = connect_value( 'postal_code', $parent, $child, 'child' );
180 if ( !connect_is_postalcode($code) ) {
181 form_set_error('', 'Please enter a valid postal code.');
182 }
183 break;
184
185 case 'lookup':
186 $return = array();
187 $use_cache = (connect_node_options($parent->nid, 'mp_lookup_cache') == 'yes');
188 $mtc_key = connect_node_options($parent->nid, 'makethechange_key');
189 $postalcode = connect_value('postal_code', $parent, $child, 'child');
190 $edid = _connect_get_riding($mtc_key, $postalcode, 'federal', 'federal', $use_cache);
191 if ($edid) {
192 // save the riding in the child node
193 connect_value('lookup_mp_data_edid', $parent, $child, 'child', $edid[0]['id']);
194
195 /* Danger! in rare cases there may be > 1 matches: this
196 * just grabs the first one; if this is a problem,
197 * use the CCK MPautocomplete version to allow users to select a riding
198 * or write a two-stage version of the participation form
199 */
200 $mp = _connect_get_MP_by_EDID($mtc_key, $edid[0]['id'], $use_cache);
201 if (!empty($mp)){
202 $return['name'] = $mp->mp_name;
203 $return['email'] = $mp->email;
204 $return['fax'] = $mp->fax;
205 }
206 else {
207 watchdog('connect', "connect_lookup_mp: MP not found for $edid[0][id]");
208 }
209 }
210 else {
211 watchdog('connect', "connect_lookup_mp: EDID not found for $postalcode");
212 }
213
214 return $return;
215 break;
216 }
217 }
218
219 /*
220 * function to look up contact info for Canadian MP -- Autocomplete version
221 * requires MP autocomplete and riding selection fields
222 *
223 * uses the OpenConcept Consulting web service at http://makethechange.ca/
224 * which requires a client key
225 *
226 */
227 function connect_lookup_mp_autocomplete($op='lookup', &$parent, &$child) {
228 switch ($op) {
229 case 'describe' :
230 return 'Canadian MP (autocomplete + riding list)';
231 break;
232
233 case 'requires':
234 $return['variables'] = array(
235 'makethechange_key' => array(
236 '#type' => 'textfield',
237 '#title' => 'Makethechange web service key',
238 '#default_value' => connect_node_options( $parent->nid, 'makethechange_key' ),
239 '#required' => TRUE,
240 ),
241 'mp_autocomplete_lookup_cache' => array(
242 '#type' => 'radios',
243 '#title' => 'Cache the lookup data?',
244 '#options' => array( 'no' => 'No', 'yes' => 'Yes'),
245 '#default_value' => connect_node_options( $parent->nid, 'mp_autocomplete_lookup_cache'),
246 '#required' => TRUE,
247 ),
248 );
249 $return['child'] = array(
250 'riding_auto' => 'MP autocomplete field',
251 'riding_list' => 'Riding list (to be selected if autocomplete fails)',
252 );
253 return $return;
254
255 case 'cache' :
256 return array(
257 'EDID2MP' => 'Federal riding to MP',
258 'pc2riding_federal_federal_ca' => 'Postal code to Federal riding'
259 );
260 break;
261
262 case 'validate' :
263 $map = connect_get_map($parent->nid);
264 $riding_auto = $child[$map['riding_auto']][0]['value'];
265 $riding_list = $child[$map['riding_list']]['key'];
266 if ( empty($riding_auto) && empty($riding_list) ) {
267 form_set_error('', 'Please enter your postal code or select your riding from the list.');
268 }
269 break;
270
271 case 'lookup':
272 $edid = 0;
273 $use_cache = (connect_node_options($parent->nid, 'mp_autocomplete_lookup_cache') == 'yes');
274 $riding_auto = connect_value( 'riding_auto', $parent, $child, 'child' );
275 $riding_list = connect_value( 'riding_list', $parent, $child, 'child' );
276 if ( !empty($riding_list) ) {
277 $edid = (int) $riding_list;
278 }
279 if ( $edid == 0 && !empty($riding_auto) ) {
280 list($id,$discard) = sscanf($riding_auto, "%d | %s");
281 $edid = (int) $id;
282 }
283
284 // do the lookup
285 if ( is_numeric($edid) ) {
286 $mtc_key = connect_node_options( $parent->nid, 'makethechange_key' );
287 $mp = _connect_get_MP_by_EDID( $mtc_key, $edid, $use_cache);
288 if ($mp ){
289 $return['name'] = $mp->mp_name;
290 $return['email'] = $mp->email;
291 $return['fax'] = $mp->fax;
292 return $return;
293 }
294 } else {
295 die('problem!');
296 }
297 return null;
298 }
299 }
300
301
302 //Ontario MPP lookup based on edid
303 //This function returns an mpp object containing contact information for the MPP
304 //it uses http://makethechange.ca to make the lookup
305 function _connect_get_ontario_MPP_by_EDID($service_key = NULL, $edid = NULL, $use_cache = FALSE) {
306 if (is_numeric($edid)) {
307
308 // cached value?
309 if ($use_cache) {
310 $cached = _connect_cached_value('EDID2MPP', $edid);
311 if (!empty($cached)) {
312 drupal_set_message( '_connect_get_ontario_MPP_by_EDID cache hit' );
313 return $cached;
314 }
315 }
316
317 // do lookup if no cached value found
318 if ($service_key) {
319 _connect_json_support(); // make sure we have JSON support
320
321 $mp_url = 'http://makethechange.ca/provincial/on_riding.php?type=json&key='.urlencode($service_key).'&edid='.$edid;
322 $fh = fopen($mp_url, "r") or watchdog('debug','MPP fopen failed: ' . $mp_url );
323 $mp_info = fread($fh, 8192) or watchdog('debug','MPP fread failed: ' . $mp_url );
324 fclose($fh);
325
326 if (!empty($mp_info)) {
327 if (!strpos($mp_info, 'Error:')) {
328 $return = json_decode(trim($mp_info));
329 if ($use_cache) {
330 $cached = _connect_cached_value('EDID2MPP', $edid, $return);
331 drupal_set_message( '_connect_get_ontario_MPP_by_EDID cache set' );
332 }
333 return $return;
334 }
335 else {
336 watchdog('connect', "_connect_get_ontario_MPP_by_EDID $mp_info");
337 }
338 }
339 else {
340 watchdog('connect', "_connect_get_ontario_MPP_by_EDID lookup returned empty MP data for $edid");
341 }
342 }
343 }
344
345 // parameter and lookup errors fall through here
346 watchdog('connect', "_connect_get_ontario_MPP_by_EDID missing EDID or service key");
347 return NULL;
348 }
349
350
351 // MP lookup using EDID
352 function _connect_get_MP_by_EDID($service_key = NULL, $edid = NULL, $use_cache = FALSE) {
353 if (is_numeric($edid)) {
354 // cached value?
355 if ($use_cache) {
356 $cached = _connect_cached_value('EDID2MP', $edid);
357 if (!empty($cached)) {
358 drupal_set_message( '_connect_get_MP_by_EDID cache hit' );
359 return $cached;
360 }
361 }
362
363 // do lookup
364 if ($service_key) {
365 _connect_json_support(); // make sure we have JSON support
366 $mp_url = 'http://makethechange.ca/federal/riding.php?type=json&key='.urlencode($service_key).'&edid='.$edid;
367 $fh = fopen($mp_url, "r") or watchdog('debug','fopen failed: ' . $mp_url );
368 $mp_info = fread($fh, 8192) or watchdog('debug','fread failed: ' . $mp_url );
369 fclose($fh);
370 if (!empty($mp_info)) {
371 if (!strpos($mp_info, 'Error:')) {
372 $return = json_decode(trim($mp_info));
373 if (empty($return->mp_name)) {
374 $return->mp_name = $return->FirstName .' '. $return->LastName;
375 }
376 if ($use_cache) {
377 $cached = _connect_cached_value('EDID2MP', $edid, $return);
378 drupal_set_message( '_connect_get_MP_by_EDID cache set' );
379 }
380 return $return;
381 }
382 else {
383 watchdog('connect', "get_MP_by_EDID $mp_info");
384 }
385 }
386 else {
387 watchdog('connect', "get_MP_by_EDID lookup returned empty MP data for $edid");
388 }
389 }
390 }
391
392 // parameter and lookup errors fall through here
393 watchdog('connect', "get_MP_by_EDID missing EDID or service key");
394 return NULL;
395 }
396
397
398 /*
399 * generic riding lookup
400 *
401 * @parameters
402 * postalcode (string)
403 * scope (string) : 'federal'|'provincial'
404 * detail (string) : 'ontario', 'ottawa', etc.
405 *
406 * @return
407 * (array) of riding info = array( 'id'=>'', 'en'=>'', 'fr'=>'' )
408 *
409 * TODO - fix the web service API.
410 *
411 */
412 function _connect_get_riding($service_key = NULL, $postalcode = NULL, $scope='federal', $detail = 'federal', $use_cache = FALSE) {
413 // verify and normalize postalcode format
414 if (!connect_is_postalcode($postalcode)) {
415 return;
416 }
417 $postalcode = strtoupper(preg_replace('/\s/', '', $postalcode));
418 $return = FALSE;
419 $cache = 'pc2riding_' . $scope . '_' . $detail . '_ca';
420
421 // cached value?
422 if ($use_cache) {
423 $cached = _connect_cached_value($cache, $postalcode);
424 if(!empty($cached)) {
425 drupal_set_message( '_connect_get_riding cache hit' );
426 return $cached;
427 }
428 }
429
430 // look up data, if not found in cache
431 // determine lookup URI based on type of lookup
432 $scope_function = array (
433 'federal' => array ( 'federal' => 'pc2csv/index' ),
434 'provincial' => array ( 'ontario' => 'provincial/on_riding' ),
435 'municipal' => array (),
436 );
437
438 if ( $service_key && isset($scope_function[$scope][$detail]) ) {
439 $riding_url = 'http://makethechange.ca/' .$scope_function[$scope][$detail]. '.php?key='.urlencode($service_key).'&pc='.urlencode($postalcode).'&type=riding';
440 $fh = fopen($riding_url, "r") or watchdog('debug','fopen failed: ' . $riding_url );
441 $riding_data = fread($fh, 200) or watchdog('debug','fread failed: ' . $riding_url );
442 fclose($fh);
443 }
444
445 // if there are results, walk through them and create an array of arrays
446 if (!empty($riding_data)) {
447 $row_token = strtok($riding_data, "\n");
448 while ($row_token != false) {
449 $return[] = connect_riding_data($row_token);
450 $row_token = strtok("\n");
451 }
452
453 // cache, if desired, and not error message
454 if ($use_cache && strpos($riding_data,'Error :') === FALSE) {
455 $cached = _connect_cached_value($cache, $postalcode, $return);
456 drupal_set_message( '_connect_get_riding cache set' );
457 }
458 }
459
460 return $return;
461 }
462
463
464 // turns riding data returned from web service into an indexed array
465 function connect_riding_data($data = NULL) {
466 $return = null;
467 $array_keys = array('id','en','fr');
468 $array_temp = explode(',',$data);
469 for ($i = 0; $i < count($array_temp); $i++) {
470 $return[$array_keys[$i]] = trim( $array_temp[$i] );
471 }
472 return $return;
473 }
474
475
476
477 /**** Utility functions ****/
478
479
480 /*
481 * Determine available target lookup types, return in select list format
482 */
483 function connect_get_lookup_types($select = FALSE) {
484 static $return = array();
485 $empty = array();
486 if (empty($return) ) {
487 $functions = get_defined_functions();
488 $array = $functions['user'];
489 foreach ($array as $key=>$name ) {
490 if (strpos($name, 'connect_lookup_') !== FALSE ) {
491 eval( '$label = '.$name.'(\'describe\', $empty, $empty);' );
492 $return[$name] = $label;
493 }
494 }
495 $return[0] = '';
496 asort($return);
497 }
498 return $return;
499 }
500
501 /*
502 * Wrappers for JSON support if this version/install of PHP
503 * doesn't support it natively
504 *
505 * Thanks to http://abeautifulsite.net/notebook/71
506 * JSON library from http://mike.teczno.com/json.html
507 */
508 function _connect_json_support() {
509 if (!function_exists('json_encode')) {
510 require_once('JSON.php');
511 function json_encode($data) {
512 $json = new Services_JSON();
513 return($json->encode($data));
514 }
515 }
516
517 if (!function_exists('json_decode')) {
518 require_once('JSON.php');
519 function json_decode($data) {
520 $json = new Services_JSON();
521 return($json->decode($data));
522 }
523 }
524 }
525
526 // check the connect cache for a saved value for a lookup
527 // if no third param = getter; third value = setter
528 function _connect_cached_value($type = NULL, $source = NULL, $value = NULL) {
529 $return = FALSE;
530 if ($type && $source) {
531 // normalize the source string: only numbers and uppercase letters
532 $source = strtoupper($source);
533 $source = preg_replace('/[^0-9A-Z]/', '', $source);
534
535 if (!$value) {
536 $sql = "SELECT target from {connect_cache} WHERE type='%s' AND source = '%s';";
537 $result = db_query($sql, $type, $source);
538 if ($row = db_fetch_object($result)) {
539 $return = unserialize($row->target);
540 }
541 }
542 else {
543 // delete
544 $sql = "DELETE from {connect_cache} WHERE type='%s' AND source = '%s';";
545 $result = db_query($sql, $type, $source);
546 //insert
547 $sql = "INSERT INTO {connect_cache} (type, source, target, created) VALUES('%s', '%s', '%s', %d);";
548 $result = db_query($sql, $type, $source, serialize($value), time());
549 $return = $result;
550 }
551 }
552 return $return;
553 }
554
555 // return names for cached items
556 function _connect_get_cache_names() {
557 $cache_names = array();
558 $lookup_types = connect_get_lookup_types(TRUE);
559 unset($lookup_types[0]);
560 $empty = array();
561 foreach ($lookup_types as $key=>$title) {
562 if (function_exists($key)) {
563 eval('$temp = ' . $key . '(\'cache\', $empty, $empty);');
564 $cache_names = array_merge($cache_names, $temp);
565 }
566 }
567 return array_unique($cache_names);
568 }

  ViewVC Help
Powered by ViewVC 1.1.2