/[drupal]/contributions/modules/civicluster/civicluster.module
ViewVC logotype

Contents of /contributions/modules/civicluster/civicluster.module

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


Revision 1.1 - (show annotations) (download) (as text)
Tue Apr 10 04:57:40 2007 UTC (2 years, 7 months ago) by straussd
Branch: MAIN
CVS Tags: HEAD
Branch point for: DRUPAL-5
File MIME type: text/x-php
initial commits for civicluster and quickform
1 <?php
2
3 /**
4 * Valid permissions for this module
5 * @return array An array of valid permissions for the civicluster module
6 */
7 function civicluster_perm()
8 {
9 return array('list similar contacts', 'merge contacts');
10 }
11
12 /**
13 * Generate HTML for the civicluster block
14 * @param op the operation from the URL
15 * @param delta offset
16 * @returns block HTML
17 */
18 function civicluster_block($op = 'list', $delta = 0)
19 {
20 // listing of blocks, such as on the admin/block page
21 if ($op == "list")
22 {
23 $block[0]["info"] = t('CiviCluster');
24 return $block;
25 }
26 else if ($op == 'view' && _civicluster_get_contact_id())
27 {
28 $cid = _civicluster_get_contact_id();
29
30 //$start = microtime(true);
31 $block_content = _civicluster_get_block_contents($cid);
32
33 if ($block_content == '')
34 return;
35 //$stop = microtime(true);
36 $block_content .= l('Compare and merge', 'civicluster/' . $cid . '/view');
37 //$block_content .= '<br />Execution Time: ' . ($stop - $start) . 's';
38
39 $block['subject'] = 'Similar contacts';
40 $block['content'] = $block_content;
41 return $block;
42 }
43 }
44
45 function civicluster_menu($may_cache)
46 {
47 $items = array();
48 if ($may_cache)
49 {
50 $items[] = array(
51 'path' => 'civicluster',
52 'title' => t('CiviCluster'),
53 'access' => user_access('list similar contacts'),
54 'callback' => 'civicluster_router',
55 'type' => MENU_CALLBACK,
56 );
57 }
58 return $items;
59 }
60
61 function civicluster_router($primary_cid = NULL, $op = NULL, $similar_cid = NULL)
62 {
63 if (($op == 'view' || $op == '') && is_numeric($primary_cid))
64 {
65 return _civicluster_view($primary_cid);
66 }
67 else if ($op == 'merge' && is_numeric($primary_cid) && is_numeric($similar_cid))
68 {
69 return _civicluster_merge($primary_cid, $similar_cid);
70 }
71
72 drupal_not_found();
73 }
74
75 function _civicluster_view($primary_cid)
76 {
77 civicrm_initialize(true);
78 $primary_contact = crm_get_contact(array('contact_id' => $primary_cid));
79 drupal_set_title('Comparing with <strong>' . $primary_contact->display_name . '</strong>');
80 return drupal_get_form('civicluster_view_form', $primary_contact);
81 }
82
83 function _civicluster_merge($primary_cid, $similar_cid)
84 {
85 if (!user_access('merge contacts'))
86 {
87 drupal_access_denied();
88 return;
89 }
90
91 civicrm_initialize(true);
92 $contacts = array(
93 'primary' => crm_get_contact(array('contact_id' => $primary_cid)),
94 'similar' => crm_get_contact(array('contact_id' => $similar_cid)),
95 );
96
97 drupal_set_title('Reconciling <strong>' . $contacts['primary']->display_name . '</strong> and <strong>' . $contacts['similar']->display_name . '</strong>');
98 return drupal_get_form('civicluster_merge_form', $contacts);
99 }
100
101 function _civicluster_choice($field, $title, $primary_value, $similar_value, $labels = array())
102 {
103 $options = array();
104
105 //drupal_set_message('Similar: ' . $similar_value);
106 //drupal_set_message('Primary: ' . $primary_value);
107 if ($similar_value != '')
108 {
109 $options[$similar_value] = $similar_value;
110 $default_value = $similar_value;
111 if (isset($labels[$similar_value]))
112 {
113 $options[$similar_value] = $labels[$similar_value];
114 }
115 }
116
117 if ($primary_value != '')
118 {
119 $options[$primary_value] = $primary_value;
120 $default_value = $primary_value;
121 if (isset($labels[$primary_value]))
122 {
123 $options[$primary_value] = $labels[$primary_value];
124 }
125 }
126
127 if (count($options) > 1)
128 {
129 return array(
130 '#type' => 'select',
131 '#title' => $title,
132 '#options' => $options,
133 '#default_value' => $default_value,
134 );
135 }
136
137 //drupal_set_message('Default: ' . $default_value);
138 return array(
139 '#type' => 'hidden',
140 '#value' => $default_value,
141 );
142 }
143
144 function _civicluster_choice_section($title, $base_form, $primary_contact, $similar_contact, $section = NULL)
145 {
146 $form = array();
147 $primary_contact = (array) $primary_contact;
148 $similar_contact = (array) $similar_contact;
149
150 // Traverse base form to get a good order
151 $added_field = FALSE;
152 foreach($base_form as $field => $attributes)
153 {
154 if (isset($primary_contact[$field]) || isset($similar_contact[$field]))
155 {
156 $primary_value = $primary_contact[$field];
157 $similar_value = $similar_contact[$field];
158 if (!is_object($primary_value) && !is_array($primary_value) && $primary_value != $similar_value)
159 {
160 // Load title first without section prefix
161 $field_title = $base_form[$field]['#title'];
162 $options = $base_form[$field]['#options'];
163 if (isset($section))
164 {
165 $field = $section . '_' . $field;
166 }
167 if (isset($base_form[$field]['#title']))
168 {
169 $field_title = $base_form[$field]['#title'];
170 }
171
172 //drupal_set_message('Field: ' . print_r($base_form[$field], TRUE));
173
174 $form[$field] = _civicluster_choice($field, $field_title, $primary_value, $similar_value, $options);
175 if ($form[$field]['#type'] != 'hidden')
176 $added_field = TRUE;
177 }
178 }
179 }
180
181 if ($added_field)
182 {
183 $form['#type'] = 'fieldset';
184 $form['#title'] = $title;
185 }
186
187 return $form;
188 }
189
190 function _civicluster_map_locations($locations)
191 {
192 $types = array();
193 foreach($locations as $location)
194 {
195 $types[$location->location_type_id] = $location;
196 }
197 return $types;
198 }
199
200 // Silly workaround
201 class _civicluster_civicrm_form
202 {
203 function assign() {}
204
205 function get($contact_type)
206 {
207 $quickform = new quickform();
208 civicrm_initialize(TRUE);
209 require_once(str_replace('_', DIRECTORY_SEPARATOR, "CRM_Contact_Form_" . $contact_type) . ".php");
210 eval( 'CRM_Contact_Form_' . $contact_type . '::buildQuickForm($quickform);' );
211 //$quickform->drupal_debug();
212 return $quickform->drupal_get_form();
213 }
214 }
215
216 function _civicluster_find_location_id($locations, $location_id)
217 {
218 foreach($locations as $location)
219 {
220 if ($location->id == $location_id)
221 return $location;
222 }
223 return FALSE;
224 }
225
226 function civicluster_merge_form($contacts)
227 {
228 $form = array();
229
230 /*
231 * Fetch complete records
232 */
233 civicrm_initialize(TRUE);
234 $primary_contact = $contacts['primary'];
235 $similar_contact = $contacts['similar'];
236
237 $form['primary_cid'] = array(
238 '#type' => 'hidden',
239 '#value' => $primary_contact->id,
240 );
241 $form['similar_cid'] = array(
242 '#type' => 'hidden',
243 '#value' => $similar_contact->id,
244 );
245
246 /*
247 * Basic contact fields
248 */
249 $get_form_obj = new _civicluster_civicrm_form();
250 $base_form = $get_form_obj->get($primary_contact->contact_type);
251
252 $primary_contact_basic = array_merge((array) $primary_contact, (array) $primary_contact->contact_type_object);
253 $similar_contact_basic = array_merge((array) $similar_contact, (array) $similar_contact->contact_type_object);
254
255 $form['basic'] = _civicluster_choice_section('Basic attributes', $base_form, $primary_contact_basic, $similar_contact_basic, 'contact');
256
257 /*
258 * Location fields
259 */
260 require_once 'CRM/Core/SelectValues.php';
261 $location_types = CRM_Core_PseudoConstant::locationType();
262
263 $primary_locations = _civicluster_map_locations($primary_contact->location);
264 $similar_locations = _civicluster_map_locations($similar_contact->location);
265
266 foreach($primary_locations as $location_type_id => $primary_location)
267 {
268 if (isset($similar_locations[$location_type_id]))
269 {
270 $similar_location = $similar_locations[$location_type_id];
271
272 $location_choices['location_' . $similar_location->id] = array(
273 '#type' => 'select',
274 '#title' => $location_types[$location_type_id],
275 '#options' => array(
276 0 => 'From ' . $primary_contact->display_name . ' (Primary contact)',
277 $primary_location->id => 'From ' . $similar_contact->display_name . ' (Similar contact)',
278 ),
279 );
280 }
281 }
282
283 if (count($location_choices) > 0)
284 {
285 $form['location'] = $location_choices;
286 $form['location']['#type'] = 'fieldset';
287 $form['location']['#title'] = t('Locations');
288 }
289
290 $form[] = array(
291 '#type' => 'submit',
292 '#value' => t('Merge contacts'),
293 );
294
295 //drupal_set_message('<pre>' . print_r($form, TRUE) . '</pre>');
296
297 return $form;
298 }
299
300 function _civicluster_filter_prefix($values, $prefix)
301 {
302 $prefix .= '_';
303 $filtered = array();
304 //print_r($values);
305 //die();
306 echo $prefix;
307 foreach($values as $name => $value)
308 {
309 if (substr($name, 0, strlen($prefix)) == $prefix)
310 {
311 $filtered[substr($name, strlen($prefix))] = $value;
312 }
313 }
314 //drupal_set_message(print_r($filtered, TRUE));
315 //die($prefix);
316 return $filtered;
317 }
318
319 function _civicluster_update_foreign_key($table, $primary_cid, $similar_cid, $field)
320 {
321 if (is_numeric($primary_cid) && is_numeric($similar_cid))
322 {
323 // Attempt to move over
324 // Must, unfortunately, be update ignore to skip the myriad of possible key conflicts
325 $sql = 'UPDATE IGNORE ' . $table . ' SET ' . $field . ' = ' . $primary_cid . ' WHERE ' . $field . ' = ' . $similar_cid;
326 if (strpos($field, 'entity_id') !== FALSE)
327 $sql .= ' AND ' . str_replace('_id', '_table', $field) . ' = "civicrm_contact"';
328 $params = array();
329 $ret = CRM_Core_DAO::executeQuery($sql, $params);
330 if (PEAR::isError($ret))
331 return FALSE;
332
333 // If a key conflicted, the record will remain with the similar_cid value
334 // Erase these
335 $sql = 'DELETE FROM ' . $table . ' WHERE ' . $field . ' = ' . $similar_cid;
336 if (strpos($field, 'entity_id') !== FALSE)
337 $sql .= ' AND ' . str_replace('_id', '_table', $field) . ' = "civicrm_contact"';
338 $params = array();
339 $ret = CRM_Core_DAO::executeQuery($sql, $params);
340 if (PEAR::isError($ret))
341 return FALSE;
342
343 return TRUE;
344 }
345 return FALSE;
346 }
347
348 function _civicluster_merge_error($text)
349 {
350 drupal_set_message('Merge error: ' . $text . ' The merge operation has been safely rolled back.', 'error');
351 }
352
353 function civicluster_merge_form_submit($form_id, $form_values)
354 {
355 if (!user_access('merge contacts'))
356 {
357 drupal_access_denied();
358 }
359
360 //drupal_set_message('<pre>' . print_r($form_values, TRUE) . '</pre>');
361
362 // Load the actual contact records
363 civicrm_initialize(TRUE);
364 $primary_contact = crm_get_contact(array('contact_id' => $form_values['primary_cid']));
365 $similar_contact = crm_get_contact(array('contact_id' => $form_values['similar_cid']));
366
367 // Wrap all the changes in a transaction
368 CRM_Core_DAO::transaction('BEGIN');
369
370 // Update primary contact record
371 $res = crm_update_contact($primary_contact, _civicluster_filter_prefix($form_values, 'contact'));
372 if (!($res instanceof CRM_Contact_BAO_Contact))
373 {
374 CRM_Core_DAO::transaction('ROLLBACK');
375 _civicluster_merge_error(t("Updating the primary contact's basic data failed."));
376 //drupal_set_message('<pre>' . print_r($res, TRUE) . '</pre>');
377 return;
378 }
379
380 // Update locations
381 $location_map = _civicluster_filter_prefix($form_values, 'location');
382 //die();
383 //drupal_set_message(print_r($location_map, TRUE));
384 //return;
385 foreach($similar_contact->location as $similar_location)
386 {
387 //drupal_set_message('Examining similar location ' . $similar_location->id);
388
389 // If the location was identified as conflicting and a replacement was selected
390 if ($location_map[$similar_location->id] > 0)
391 {
392 //drupal_set_message('Deleting conflicting location');
393 // Delete the conflicting location
394 $ret = crm_delete_location($primary_contact, $location_map[$similar_location->id]);
395 if (PEAR::isError($ret))
396 {
397 CRM_Core_DAO::transaction('ROLLBACK');
398 _civicluster_merge_error(t("Deleting the primary contact's conflicting locations failed."));
399 return;
400 }
401 }
402
403 // If a replacement was selected or no conflict existed
404 if ($location_map[$similar_location->id] > 0 || !isset($location_map[$similar_location->id]))
405 {
406 //drupal_set_message('Moving in similar location');
407 // Move in the new one
408 $sql = 'UPDATE civicrm_location SET entity_id = ' . $primary_contact->id . ' WHERE id = ' . $similar_location->id;
409 $params = array();
410 $ret = CRM_Core_DAO::executeQuery($sql, $params);
411 if (PEAR::isError($ret))
412 {
413 CRM_Core_DAO::transaction('ROLLBACK');
414 _civicluster_merge_error(t("Updating the primary contact's locations failed."));
415 return;
416 }
417 }
418 }
419
420 // Update many-to-one records
421 $updates = array();
422 $updates[] = array('civicrm_sms_history');
423 $updates[] = array('civicrm_activity', 'source_contact_id');
424 $updates[] = array('civicrm_activity', 'target_entity_id');
425 $updates[] = array('civicrm_email_history');
426 $updates[] = array('civicrm_note', 'entity_id');
427 $updates[] = array('civicrm_uf_match');
428 $updates[] = array('civicrm_log', 'entity_id');
429 $updates[] = array('civicrm_subscription_history');
430 $updates[] = array('civicrm_relationship', 'contact_id_a');
431 $updates[] = array('civicrm_relationship', 'contact_id_b');
432 $updates[] = array('civicrm_mailing_event_subscribe');
433 $updates[] = array('civicrm_membership_type', 'member_of_contact_id');
434 $updates[] = array('civicrm_membership');
435 $updates[] = array('civicrm_membership_log', 'modified_id');
436 $updates[] = array('civicrm_phonecall', 'source_contact_id');
437 $updates[] = array('civicrm_group_contact');
438 $updates[] = array('civicrm_mailing_event_queue');
439 $updates[] = array('civicrm_contribution');
440 $updates[] = array('civicrm_contribution', 'solicitor_id');
441 $updates[] = array('civicrm_contribution', 'honor_contact_id');
442 $updates[] = array('civicrm_contribution_recur');
443 $updates[] = array('civicrm_mailing_group', 'entity_id');
444 $updates[] = array('civicrm_financial_trxn', 'entity_id');
445 $updates[] = array('civicrm_premiums', 'entity_id');
446 $updates[] = array('civicrm_project', 'owner_entity_id');
447 $updates[] = array('civicrm_task', 'owner_entity_id');
448 $updates[] = array('civicrm_task', 'parent_entity_id');
449 $updates[] = array('civicrm_task_status', 'responsible_entity_id');
450 $updates[] = array('civicrm_task_status', 'target_entity_id');
451 $updates[] = array('civicrm_meeting', 'target_entity_id');
452 $updates[] = array('civicrm_custom_value', 'entity_id');
453 $updates[] = array('civicrm_entity_tag', 'entity_id');
454 $ret = TRUE;
455
456 foreach($updates as $update)
457 {
458 $field = 'contact_id';
459 if(isset($update[1]))
460 {
461 $field = $update[1];
462 }
463
464 $ret = _civicluster_update_foreign_key($update[0], $primary_contact->id, $similar_contact->id, $field);
465
466 if (!$ret)
467 {
468 CRM_Core_DAO::transaction('ROLLBACK');
469 _civicluster_merge_error(t('Migrating the values of %table.%field failed.', array('%table' => $update[0], '%field' => $field)));
470 return;
471 }
472 }
473
474 // Delete similar contact record
475 if (crm_delete_contact($similar_contact) !== NULL)
476 {
477 CRM_Core_DAO::transaction('ROLLBACK');
478 _civicluster_merge_error(t('Deleting the duplicate contact failed.'));
479 return;
480 }
481
482 //CRM_Core_DAO::transaction('ROLLBACK');
483 CRM_Core_DAO::transaction('COMMIT');
484
485 drupal_set_message('Contact records successfully merged.');
486 //drupal_goto('portal');
487 drupal_goto('civicrm/contact/view', 'reset=1&cid=' . $primary_contact->id);
488 }
489
490 function civicluster_view_form($primary_contact)
491 {
492 $form = array();
493
494 /*
495 * Primary contact section
496 */
497 $form['primary_cid'] = array(
498 '#type' => 'hidden',
499 '#value' => $primary_contact->id,
500 );
501
502 $form['primary'] = array(
503 '#type' => 'fieldset',
504 '#title' => $primary_contact->display_name,
505 );
506
507 $form['primary'][] = array(
508 '#type' => 'submit',
509 '#name' => 'view',
510 '#value' => t('View in CiviCRM'),
511 );
512
513 if (user_access('merge contacts'))
514 {
515 $count = db_result(db_query('SELECT COUNT(*) FROM {civicluster_separated} WHERE contact_id = %d OR contact_id_2 = %d', $primary_contact->id, $primary_contact->id));
516 if ($count > 0)
517 {
518 $form['primary'][] = array(
519 '#type' => 'submit',
520 '#name' => 'reset',
521 '#value' => t('Reset difference marks'),
522 );
523 }
524 }
525
526 $form['primary'][] = array(
527 '#value' => _civicluster_contact_attributes_table($primary_contact),
528 );
529
530 if (isset($_GET['raw']))
531 {
532 $form['primary']['raw'] = array(
533 '#type' => 'fieldset',
534 '#collapsible' => TRUE,
535 '#collapsed' => TRUE,
536 '#title' => t('Raw contact record'),
537 );
538
539 $form['primary']['raw'][] = array(
540 '#value' => '<pre>' . print_r($primary_contact, TRUE) . '</pre>',
541 );
542 }
543
544 /*
545 * Similar contacts section
546 */
547
548 $similar_cids = civicluster_get_similar($primary_contact->id);
549
550 if (count($similar_cids) > 0)
551 {
552 $form[] = array(
553 '#value' => '<h2>' . t('Similar contacts') . '</h2>',
554 );
555
556 foreach($similar_cids as $similar_cid)
557 {
558 $similar_contact = crm_get_contact(array('contact_id' => $similar_cid));
559
560 $form['similar_' . $similar_contact->id] = array(
561 '#type' => 'fieldset',
562 '#title' => $similar_contact->display_name,
563 );
564
565 if (user_access('merge contacts'))
566 {
567 $form['similar_' . $similar_contact->id][] = array(
568 '#name' => 'merge_' . $similar_contact->id,
569 '#type' => 'submit',
570 '#value' => t('Prepare to merge'),
571 );
572
573 $form['similar_' . $similar_contact->id][] = array(
574 '#name' => 'separate_' . $similar_contact->id,
575 '#type' => 'submit',
576 '#value' => t('Mark as different'),
577 );
578 }
579
580 $form['similar_' . $similar_contact->id][] = array(
581 '#value' => _civicluster_contact_attributes_table($similar_contact),
582 );
583
584 if (isset($_GET['raw']))
585 {
586 $form['similar_' . $similar_contact->id]['raw'] = array(
587 '#type' => 'fieldset',
588 '#collapsible' => TRUE,
589 '#collapsed' => TRUE,
590 '#title' => t('Raw contact record'),
591 );
592
593 $form['similar_' . $similar_contact->id]['raw'][] = array(
594 '#value' => '<pre>' . print_r($similar_contact, TRUE) . '</pre>',
595 );
596 }
597 }
598 }
599
600 return $form;
601 }
602
603 function civicluster_view_form_submit($form_id, $form_values)
604 {
605 //drupal_set_message('<pre>' . print_r($form_values, TRUE) . '</pre>');
606
607 $primary_cid = $form_values['primary_cid'];
608 foreach($form_values as $key => $value)
609 {
610 $parts = explode('_', $key);
611 if ($parts[0] == 'merge')
612 {
613 $similar_cid = $parts[1];
614 //drupal_set_message($similar_cid);
615 //civicluster_merge($primary_cid, $similar_cid);
616 drupal_goto('civicluster/' . $primary_cid . '/merge/' . $similar_cid);
617 return;
618 }
619 else if ($parts[0] == 'separate')
620 {
621 $similar_cid = $parts[1];
622 $one = $primary_cid;
623 $two = $similar_cid;
624 if ($primary_cid > $similar_cid)
625 {
626 $one = $similar_cid;
627 $two = $primary_cid;
628 }
629
630 db_query('INSERT INTO {civicluster_separated} VALUES (%d, %d)', $one, $two);
631
632 drupal_set_message('Marked the two contacts are separate records.');
633 return;
634 }
635 else if ($parts[0] == 'reset')
636 {
637 db_query('DELETE FROM {civicluster_separated} WHERE contact_id = %d OR contact_id_2 = %d', $primary_cid, $primary_cid);
638 drupal_set_message('Reset all separation flags.');
639 return;
640 }
641 else if ($parts[0] == 'view')
642 {
643 //die('view');
644 drupal_goto('civicrm/contact/view', 'reset=1&cid=' . $primary_cid);
645 //return;
646 }
647 }
648 }
649
650 function civicluster_are_separated($primary_cid, $similar_cid)
651 {
652 $one = $primary_cid;
653 $two = $similar_cid;
654 if ($primary_cid > $similar_cid)
655 {
656 $one = $similar_cid;
657 $two = $primary_cid;
658 }
659
660 $count = db_result(db_query('SELECT COUNT(*) FROM {civicluster_separated} WHERE contact_id = %d AND contact_id_2 = %d', $one, $two));
661 return ($count == 1);
662 }
663
664 function _civicluster_contact_attributes_table($civicrm_contact)
665 {
666 $header = array('CiviCRM attribute', 'Value');
667 $rows = array();
668 //$rows[] = array('ID', $civicrm_contact->id);
669 $rows[] = array('Type', $civicrm_contact->contact_type);
670 return theme('table', $header, $rows);
671 }
672
673 function _civicluster_get_contact_id()
674 {
675 if (arg(0) == 'civicrm' && arg(1) == 'contact' && arg(2) == 'view')
676 {
677 return $_GET['cid'];
678 }
679 return FALSE;
680 }
681
682 function _civicluster_get_contact($cid)
683 {
684 if (!is_numeric($cid))
685 return NULL;
686
687 $sql = 'SELECT * FROM civicrm_contact WHERE id = ' . $cid;
688 $res =& CRM_Core_DAO::executeQuery( $sql, CRM_Core_DAO::$_nullArray );
689 if ($res->fetch())
690 {
691 return $res;
692 }
693 return NULL;
694 }
695
696 function _civicluster_get_display_name($contact)
697 {
698 if ($contact->display_name != '')
699 return $contact->display_name;
700 return $contact->id;
701 }
702
703 function _civicluster_get_block_contents($cid)
704 {
705 $cids = civicluster_get_similar($cid);
706 $items = array();
707
708 foreach($cids as $cid)
709 {
710 $contact =& _civicluster_get_contact($cid);
711 $items[] = '<a href="/civicrm/contact/view?reset=1&cid=' . $cid . '">' . _civicluster_get_display_name($contact) . '</a>';
712 }
713 if (count($items) == 0)
714 return '';
715
716 return theme('item_list', $items);
717 }
718
719 /*
720 * CiviCluster clustering functions
721 */
722
723 function civicluster_get_similar($primary_cid)
724 {
725 return _civicluster_get_similar_rough($primary_cid, 10);
726 }
727
728 function _civicluster_get_similar_rough($primary_cid, $min_score)
729 {
730 $similar = array();
731 $similar = _civicluster_update_scores($similar, _civicluster_get_similar_location($primary_cid, 'civicrm_address', 'street_name'), 5);
732 //$similar = _civicluster_update_scores($similar, _civicluster_get_similar_location($primary_cid, 'civicrm_address', 'city'));
733 $similar = _civicluster_update_scores($similar, _civicluster_get_similar_location($primary_cid, 'civicrm_email', 'email'), 20);
734 $similar = _civicluster_update_scores($similar, _civicluster_get_similar_location($primary_cid, 'civicrm_phone', 'phone'), 10);
735 $similar = _civicluster_update_scores($similar, _civicluster_get_similar_name($primary_cid, 6), 2);
736 $similar = _civicluster_update_scores($similar, _civicluster_get_similar_name($primary_cid, 8), 3);
737 $similar = _civicluster_update_scores($similar, _civicluster_get_similar_name($primary_cid, 10), 4);
738 $similar = _civicluster_update_scores($similar, _civicluster_get_similar_name($primary_cid, 12), 5);
739
740 //drupal_set_message(print_r($similar, TRUE));
741
742 $similar_cids = array();
743 foreach($similar as $similar_cid => $score)
744 {
745 if ($score >= $min_score && $similar_cid != $primary_cid && !civicluster_are_separated($primary_cid, $similar_cid))
746 {
747 $similar_cids[] = $similar_cid;
748 }
749 }
750
751 //print_r($ret);
752
753 return $similar_cids;
754 }
755
756 function _civicluster_get_similar_name($cid, $characters = 100)
757 {
758 if (!is_numeric($cid))
759 return array();
760
761 $sql = 'SELECT sort_name FROM civicrm_contact WHERE id = ' . $cid;
762 $res =& CRM_Core_DAO::executeQuery( $sql, CRM_Core_DAO::$_nullArray );
763 $row = $res->fetch();
764 $sort_name = $row['sort_name'];
765
766 $sql = 'SELECT id FROM civicrm_contact far WHERE sort_name LIKE "%1%%"';
767 $sort_name = substr($sort_name, 0, $characters);
768 $params = array(1 => array($sort_name, 'String'));
769 $res =& CRM_Core_DAO::executeQuery($sql, $params);
770
771 $ret = array();
772 while ($res->fetch())
773 {
774 $ret[] = $res->id;
775 }
776
777 //drupal_set_message(print_r($ret, TRUE));
778
779 return $ret;
780 }
781
782 function _civicluster_get_similar_location($cid, $table, $field)
783 {
784 if (!is_numeric($cid))
785 return array();
786
787 $sql = 'SELECT farl.entity_id AS contact_id FROM civicrm_location farl ';
788 $sql .= 'INNER JOIN ' . $table . ' fara ON fara.location_id = farl.id ';
789 $sql .= 'INNER JOIN ' . $table . ' neara ON fara.' . $field . ' = neara.' . $field . ' ';
790 $sql .= 'INNER JOIN civicrm_location nearl ON neara.location_id = nearl.id ';
791 $sql .= 'WHERE farl.entity_table = "civicrm_contact" AND nearl.entity_table = "civicrm_contact" AND nearl.entity_id = ' . $cid;
792 //drupal_set_message($sql);
793 $res =& CRM_Core_DAO::executeQuery( $sql, CRM_Core_DAO::$_nullArray );
794 $ret = array();
795 while ($res->fetch())
796 {
797 $ret[] = $res->contact_id;
798 }
799
800 //drupal_set_message(print_r($ret, TRUE));
801 //echo 'Location ' . $table . '.' . $field . ':' . "\n";
802 //print_r($ret);
803
804 return $ret;
805 }
806
807 function _civicluster_update_scores($existing, $new, $points = 1)
808 {
809 foreach ($new as $cid)
810 {
811 if (array_key_exists($cid, $existing))
812 {
813 $existing[$cid] += $points;
814 } else {
815 $existing[$cid] = $points;
816 }
817 }
818
819 return $existing;
820 }

  ViewVC Help
Powered by ViewVC 1.1.2