You are here

function webform_civicrm_contact_match in Webform CiviCRM Integration 6

Same name and namespace in other branches
  1. 7 webform_civicrm_utils.inc \webform_civicrm_contact_match()

Create or update CiviCRM contact Called by both presave and insert webform hooks in order to handle the optional contact_id field correctly

2 calls to webform_civicrm_contact_match()
webform_civicrm_process_submission in ./webform_civicrm_forms.inc
Called from hook_webform_submission_insert() Process CiviCRM contact. Create activity record.
webform_civicrm_webform_submission_presave in ./webform_civicrm.module
Implementation of hook_webform_submission_presave().

File

./webform_civicrm_utils.inc, line 13
Webform CiviCRM module's utility functions.

Code

function webform_civicrm_contact_match($node, &$submission) {
  static $cid = 0;
  if ($cid) {
    return $cid;
  }
  civicrm_initialize();
  $enabled = webform_civicrm_enabled_fields($node);
  $fields = webform_civicrm_get_fields();
  $params = array(
    'check_permission' => FALSE,
  );
  $table = 'contact';
  global $user;

  // Convert flat array to multidimensional array based on civi table names
  // This is why the order is important in webform_civicrm_get_fields()
  foreach ($fields as $fid => $field) {
    $field = str_replace('civicrm_', '', $fid);
    if ($field == 'street_address') {
      $table = 'address';
    }
    elseif ($field == 'email') {
      $table = 'email';
    }
    elseif ($field == 'phone') {
      $table = 'phone';
    }
    elseif ($field == 'groups' || $field == 'groups_hidden' || $field == 'tags') {
      $table = 'custom';
      continue;
    }
    if (!empty($submission->data[$enabled[$fid]]['value'])) {
      $val = $submission->data[$enabled[$fid]]['value'];
      if (count($val) > 1 && $table == 'custom') {
        $params['civicrm_' . $table][$field] = drupal_map_assoc($val);
      }
      elseif (!empty($val[0])) {
        $params['civicrm_' . $table][$field] = $val[0];
      }
    }
  }
  $custom = $params['civicrm_custom'];
  unset($params['civicrm_custom']);
  require_once 'api/v2/Contact.php';

  // If this is an update op, just use CID from original submission to avoid confusion
  if (!empty($submission->sid)) {
    $db = db_query('SELECT contact_id FROM {webform_civicrm_submissions} WHERE sid = ' . $submission->sid);
    if ($existing = db_fetch_array($db)) {
      $cid = $existing['contact_id'];
    }
  }
  if (!$cid) {

    // Try to match an existing contact to this submission. Logged-in user takes priority.
    if ($user->uid) {
      require_once 'CRM/Core/BAO/UFMatch.php';
      $cid = CRM_Core_BAO_UFMatch::getContactId($user->uid);
    }
    elseif ($_SESSION['webform_civicrm_cid'] && $_SESSION['webform_civicrm_cs']) {
      require_once 'CRM/Contact/BAO/Contact/Utils.php';
      if (CRM_Contact_BAO_Contact_Utils::validChecksum($_SESSION['webform_civicrm_cid'], $_SESSION['webform_civicrm_cs'])) {
        $cid = $_SESSION['webform_civicrm_cid'];
      }
    }

    // Search for an existing contact using default strict rule
    if (!$cid) {
      require_once 'CRM/Dedupe/Finder.php';
      if ($dupes = CRM_Dedupe_Finder::dupesByParams($params, 'Individual')) {
        $cid = $dupes[0];
      }
    }
  }
  $params['civicrm_contact']['contact_type'] = 'Individual';

  // Update or create new contact.
  // We call both add and update functions for new contacts, in order to avoid problems with API custom field handling.
  $op = 'update';
  if (!$cid) {
    $result = civicrm_contact_add($params['civicrm_contact']);
    $cid = $result['contact_id'];
    $op = 'create';
  }
  if ($cid) {
    if (!empty($custom)) {
      $params['civicrm_contact'] = array_merge($params['civicrm_contact'], $custom);
    }
    $params['civicrm_contact']['contact_id'] = $cid;
    $params['civicrm_contact']['check_permission'] = FALSE;
    civicrm_contact_update($params['civicrm_contact']);
  }
  else {

    // If an error occurred and we couldn't create contact, stop here.
    return;
  }

  // Fill values for hidden ID fields
  if (!empty($enabled['civicrm_contact_id'])) {
    $submission->data[$enabled['civicrm_contact_id']]['value'] = array(
      $cid,
    );
  }
  if (!empty($enabled['civicrm_external_identifier']) && $op == 'update') {
    $get_params = array(
      'contact_id' => $cid,
      'return_external_identifier' => 1,
    );
    $fetched = civicrm_contact_get($get_params);
    $submission->data[$enabled['civicrm_external_identifier']]['value'] = array(
      $fetched[$cid]['external_identifier'],
    );
  }

  // Add or update location
  $address_params = array();
  if (!empty($params['civicrm_address'])) {
    $address_params['address'][1] = $params['civicrm_address'];
    $address_params['address'][1]['is_primary'] = 1;
    $address_params['address'][1]['location_type_id'] = 1;
  }
  if (!empty($params['civicrm_email'])) {
    $address_params['email'][1] = $params['civicrm_email'];
    $address_params['email'][1]['is_primary'] = 1;
    $address_params['email'][1]['location_type_id'] = 1;
  }
  if (!empty($params['civicrm_phone'])) {
    $address_params['phone'][1] = $params['civicrm_phone'];
    if (!$params['civicrm_phone']['phone_type_id']) {
      $address_params['phone'][1]['phone_type_id'] = 1;
    }
    $address_params['phone'][1]['is_primary'] = 1;
    $address_params['phone'][1]['location_type_id'] = 1;
  }
  if ($address_params) {
    require_once 'api/v2/Location.php';
    $address_params['contact_id'] = $cid;
    $address_params['version'] = '3.0';

    // Update existing address
    $result = civicrm_location_update($address_params);

    // Or create a new one
    if ($result['is_error']) {
      $result = civicrm_location_add($address_params);
    }
  }

  // Process groups
  if (!empty($enabled['civicrm_groups']) || !empty($enabled['civicrm_groups_hidden'])) {
    require_once 'api/v2/GroupContact.php';
    $add_groups = $all_groups = $remove_groups = array();
    if (!empty($enabled['civicrm_groups'])) {
      $add_groups = $submission->data[$enabled['civicrm_groups']]['value'];
      $all_groups = explode("\n", $node->webform['components'][$enabled['civicrm_groups']]['extra']['items']);
      $remove_groups = array();
      foreach ($all_groups as $g) {
        list($gid, $group) = explode('|', $g);
        $remove_groups[$gid] = $group;
      }
    }
    if (!empty($enabled['civicrm_groups_hidden'])) {
      if (!empty($submission->data[$enabled['civicrm_groups_hidden']]['value'][0])) {
        $add_hidden = explode(',', $submission->data[$enabled['civicrm_groups_hidden']]['value'][0]);
        $add_groups = array_unique(array_merge($add_groups, $add_hidden));
      }
    }
    if ($add_groups) {

      // Prepare for sending subscription confirmations
      $confirmations_sent = array();
      if ($node->webform_civicrm['confirm_subscription']) {
        $get_params = array(
          'contact_id' => $cid,
          'return_email' => 1,
        );
        $fetched = civicrm_contact_get($get_params);
        $mailer_params = array(
          'contact_id' => $cid,
          'email' => $fetched[$cid]['email'],
        );
        $mailing_lists = webform_civicrm_get_options('mailing_lists', 'arr');
      }
      else {
        $mailing_lists = array();
      }
      $group_params = array(
        'contact_id.1' => $cid,
      );
      if (!empty($add_groups)) {
        foreach ($add_groups as $gid) {
          $group_params['group_id'] = $mailer_params['group_id'] = (int) $gid;
          unset($remove_groups[$gid]);
          if (array_key_exists($gid, $mailing_lists)) {
            webform_civicrm_mailer_event_subscribe($mailer_params);
            $confirmations_sent[] = $mailing_lists[$gid];
          }
          else {
            civicrm_group_contact_add($group_params);
          }
        }
      }
      if (!empty($confirmations_sent)) {
        drupal_set_message(t('A confirmation has been sent to your email address, please follow the instructions in that message to finalize your subscription to @groups.', array(
          '@groups' => implode(' ' . t('and') . ' ', $confirmations_sent),
        )));
      }
    }

    // Remove contact from groups if they have unchecked them on the form
    if ($remove_groups && $op == 'update') {
      $search_params = array(
        'contact_id' => $cid,
      );
      $groups = civicrm_group_contact_get($search_params);
      $in_groups = array();
      foreach ($groups as $group) {
        $in_groups[] = $group['group_id'];
      }
      $group_params = array(
        'contact_id.1' => $cid,
      );
      foreach ($remove_groups as $group_params['group_id'] => $group) {
        if (in_array($group_params['group_id'], $in_groups)) {
          civicrm_group_contact_remove($group_params);
          drupal_set_message(t('You have removed yourself from') . ' ' . $group . '.');
        }
      }
    }
  }

  // Process tags
  if (!empty($enabled['civicrm_tags'])) {
    require_once 'api/v2/Tag.php';
    require_once 'api/v2/EntityTag.php';
    $add_tags = drupal_explode_tags($submission->data[$enabled['civicrm_tags']]['value'][0]);
    foreach ($add_tags as $tag) {
      $params = array(
        'name' => $tag,
      );
      $result = civicrm_tag_get($params);

      // Create tag if it doesn't exist
      if (!($id = $result['id'])) {
        $result = civicrm_tag_create($params);
        $id = $result['tag_id'];
      }
      $params = array(
        'tag_id' => $id,
        'contact_id' => $cid,
      );
      civicrm_entity_tag_add($params);
    }
  }
  return $cid;
}