You are here

function webform_civicrm_contact_match in Webform CiviCRM Integration 7

Same name and namespace in other branches
  1. 6 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
Implements hook_webform_submission_presave().

File

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

Code

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

  // 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 (isset($enabled[$fid])) {
      $val = $submission->data[$enabled[$fid]]['value'];
      if (count($val) > 1) {
        $params['civicrm_' . $table][$field] = drupal_map_assoc($val);
      }
      elseif (isset($val[0])) {
        $params['civicrm_' . $table][$field] = $val[0];
      }
    }
  }
  if (isset($params['civicrm_custom'])) {
    $custom = $params['civicrm_custom'];
    unset($params['civicrm_custom']);
  }
  global $user;

  // 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 = :sid', array(
      ':sid' => $submission->sid,
    ));
    foreach ($db as $existing) {
      if ($cid = $existing['contact_id']) {
        break;
      }
    }
  }
  if (!$cid) {

    // Try to match an existing contact to this submission. Logged-in user takes priority.
    if ($user->uid) {
      $result = civicrm_api('uf_match', 'get', array(
        'uf_id' => $user->uid,
        'check_permissions' => FALSE,
        'version' => 3,
      ));
      if (is_array($result['values'])) {
        $result = array_pop($result['values']);
        $cid = $result['contact_id'];
      }
    }
    elseif (!empty($_SESSION['webform_civicrm_cid']) && !empty($_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'];
      }
      unset($_SESSION['webform_civicrm_cid'], $_SESSION['webform_civicrm_cs']);
    }

    // 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';
  $params['civicrm_contact']['version'] = 3;
  $params['civicrm_contact']['check_permissions'] = FALSE;

  // Update or create new contact.
  if (isset($custom)) {
    $params['civicrm_contact'] = array_merge($params['civicrm_contact'], $custom);
  }
  if (!$cid) {
    $result = civicrm_api('contact', 'create', $params['civicrm_contact']);
    $cid = $result['id'];
    $op = 'create';
  }
  else {
    $params['civicrm_contact']['contact_id'] = $cid;
    civicrm_api('contact', 'create', $params['civicrm_contact']);
    $op = 'update';
  }
  if (!$cid) {

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

  // Fill values for hidden ID fields
  if (isset($enabled['civicrm_contact_id'])) {
    $submission->data[$enabled['civicrm_contact_id']]['value'] = array(
      $cid,
    );
  }
  if (isset($enabled['civicrm_external_identifier']) && $op == 'update') {
    $exid = civicrm_api('contact', 'get', array(
      'check_permissions' => FALSE,
      'version' => 3,
      'contact_id' => $cid,
      'return_external_identifier' => 1,
    ));
    if (is_array($exid['values'])) {
      $exid = array_pop($exid['values']);
      $submission->data[$enabled['civicrm_external_identifier']]['value'] = array(
        $exid['external_identifier'],
      );
    }
  }

  // Save address, email, and phone
  foreach (array(
    'address',
    'email',
    'phone',
  ) as $location) {
    if (array_key_exists('civicrm_' . $location, $params)) {
      $address_params = $params['civicrm_' . $location];
      $address_params['check_permissions'] = FALSE;
      $address_params['version'] = 3;
      $address_params['contact_id'] = $cid;
      $address_params['is_primary'] = $address_params['location_type_id'] = 1;
      if (!isset($address_params['phone_type_id']) && $location == 'phone') {
        $address_params['phone_type_id'] = 1;
      }
      $result = civicrm_api($location, 'get', array(
        'check_permissions' => FALSE,
        'version' => 3,
        'contact_id' => $cid,
      ));
      if (!empty($result['values'])) {
        foreach ($result['values'] as $loc) {
          if ($loc['location_type_id'] == 1) {
            if ($location == 'phone') {
              if ($address_params['phone_type_id'] != $loc['phone_type_id']) {
                continue;
              }
            }
            $address_params['id'] = $loc['id'];
            break;
          }
        }
      }
      civicrm_api($location, 'create', $address_params);
    }
  }

  // Update Drupal user->mail
  if (!empty($user->uid) && !empty($params['civicrm_email']['email'])) {
    db_update('users')
      ->fields(array(
      'mail' => $params['civicrm_email']['email'],
    ))
      ->condition('uid', $user->uid)
      ->execute();
  }

  // Process groups
  if (!empty($enabled['civicrm_groups']) || !empty($enabled['civicrm_groups_hidden'])) {
    $add_groups = $add_hidden = $remove_groups = $all_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']);
      foreach ($all_groups as $g) {
        if (!empty($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 (!empty($add_groups)) {

      // Prepare for sending subscription confirmations
      $confirmations_sent = array();
      $mailing_lists = array();
      if (!empty($node->webform_civicrm['confirm_subscription'])) {
        $contact = civicrm_api('contact', 'get', array(
          'check_permissions' => FALSE,
          'version' => 3,
          'contact_id' => $cid,
          'return_email' => 1,
        ));
        $contact = array_pop($contact['values']);
        $mailer_params = array(
          'check_permissions' => FALSE,
          'version' => 3,
          'contact_id' => $cid,
          'email' => $contact['email'],
        );
        if (!empty($contact['email'])) {
          $mailing_lists = webform_civicrm_get_options('mailing_lists', 'arr');
        }
      }
      $group_params = array(
        'contact_id' => $cid,
        'check_permissions' => FALSE,
        'version' => 3,
      );
      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)) {
            civicrm_api('mailing_group', 'event_subscribe', $mailer_params);
            $confirmations_sent[] = $mailing_lists[$gid];
          }
          else {
            civicrm_api('group_contact', 'create', $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 (!empty($remove_groups) && $op == 'update') {
      $groups = civicrm_api('group_contact', 'get', array(
        'contact_id' => $cid,
        'check_permissions' => FALSE,
        'version' => 3,
      ));
      $in_groups = array();
      if (is_array($groups['values'])) {
        foreach ($groups['values'] as $group) {
          $in_groups[] = $group['group_id'];
        }
      }
      $group_params = array(
        'contact_id' => $cid,
        'check_permissions' => FALSE,
        'version' => 3,
      );
      foreach ($remove_groups as $group_params['group_id'] => $group) {
        if (in_array($group_params['group_id'], $in_groups)) {
          civicrm_api('group_contact', 'delete', $group_params);
          drupal_set_message(t('You have removed yourself from') . ' ' . check_plain($group) . '.');
        }
      }
    }
  }

  // Process tags
  if (array_key_exists('civicrm_tags', $enabled)) {
    $add_tags = drupal_explode_tags($submission->data[$enabled['civicrm_tags']]['value'][0]);
    foreach ($add_tags as $tag) {
      $result = civicrm_api('tag', 'get', array(
        'name' => $tag,
        'check_permissions' => FALSE,
        'version' => 3,
      ));

      // Create tag if it doesn't exist
      if (!($id = $result['id'])) {
        $result = civicrm_api('tag', 'create', array(
          'name' => $tag,
          'check_permissions' => FALSE,
          'version' => 3,
        ));
        $id = $result['id'];
      }
      civicrm_api('entity_tag', 'create', array(
        'contact_id' => $cid,
        'tag_id' => $id,
        'check_permissions' => FALSE,
        'version' => 3,
      ));
    }
  }
  return $cid;
}