You are here

function redhen_dedupe_merge_form in RedHen CRM 7

Form to select the master contact.

1 string reference to 'redhen_dedupe_merge_form'
redhen_dedupe_menu in modules/redhen_dedupe/redhen_dedupe.module
Implements hook_menu().

File

modules/redhen_dedupe/includes/redhen_dedupe.form.inc, line 13
Forms for creating, editing, and deleting contacts.

Code

function redhen_dedupe_merge_form($form, &$form_state, $entity_ids) {

  // Load the entities we want to merge:
  $entity_ids = explode(',', $entity_ids);
  $contacts = redhen_contact_load_multiple($entity_ids);
  $master_options = array();

  // Loop through the entities to build out our master entity options:
  foreach ($contacts as $ent_id => $entity) {
    $wrapper = entity_metadata_wrapper('redhen_contact', $entity);
    $updated = format_date($wrapper->updated
      ->value(), 'short');
    $master_options[$ent_id] = t('@name (Updated: !date)', array(
      '!date' => $updated,
      '@name' => $wrapper
        ->label(),
    ));
  }

  // Form field to select a merge master entity.
  $form['master'] = array(
    '#type' => 'radios',
    '#title' => t('Master Contact'),
    '#default_value' => key($master_options),
    '#required' => TRUE,
    '#options' => $master_options,
    '#description' => t('Choose a contact to merge the other contacts into.'),
    '#weight' => 0,
    '#ajax' => array(
      'callback' => 'redhen_dedupe_merge_form_callback',
      'wrapper' => 'redhen_dedupe_merge_data',
    ),
  );
  $form['merge_data'] = array(
    '#type' => 'container',
    '#attributes' => array(
      'id' => 'redhen_dedupe_merge_data',
    ),
  );
  $master_id = isset($form_state['values']['master']) ? (int) $form_state['values']['master'] : key($master_options);
  $merge_data =& $form['merge_data'];
  $preview = $contacts[$master_id]
    ->view();
  $merge_data['contact_preview'] = array(
    '#type' => 'fieldset',
    '#title' => t('Master contact details'),
    'preview' => array(
      '#markup' => render($preview),
    ),
  );

  // Initialize our table header:
  $table_header = array(
    t('Field Name'),
  );

  // Loop through the entities to build out our table headers and master
  // entity options:
  foreach ($contacts as $ent_id => $contact) {
    $wrapper = entity_metadata_wrapper('redhen_contact', $contact);
    $updated = format_date($wrapper->updated
      ->value(), 'short');
    $header_data = array(
      '!date' => $updated,
      '@name' => $wrapper
        ->label(),
      '@bundle' => $wrapper
        ->getBundle(),
      '@master' => $ent_id == $master_id ? t('Master') . ': ' : '',
    );
    $table_header[$ent_id] = array(
      'data' => t('@master@name (@bundle)<br/>Last Updated: !date', $header_data),
      'class' => $ent_id == $master_id ? 'redhen-dedupe-master-col' : 'redhen-dedupe-col',
    );
  }

  // Pass along the entity ID options & master ID to the form handler:
  $form_state['contacts'] = $contacts;

  // Now we build our merge selector form fields:
  $merge_data['values'] = array(
    '#theme' => 'redhen_dedupe_form_table',
    '#tree' => TRUE,
    '#header' => $table_header,
  );
  $info = entity_get_property_info('redhen_contact');
  $properties = entity_get_all_property_info('redhen_contact');

  // Loop through each property and build a form element for it. The form
  // element will be placed into a table in redhen_dedupe_form_table:
  $master_wrapper = entity_metadata_wrapper('redhen_contact', $contacts[$master_id]);
  foreach ($properties as $name => $property) {

    // Skip property if it does not exist on the master record.
    if (!isset($master_wrapper->{$name})) {
      continue;
    }

    // Call a helper function to determine if this is a field we want to merge:
    if (redhen_dedupe_property_mergeable($name, $property)) {

      // Need this due to a FAPI bug (https://drupal.org/node/1634364).
      if (isset($form_state['input']['values'][$name])) {
        unset($form_state['input']['values'][$name]);
      }
      $is_field = isset($properties[$name]['field']) && $properties[$name]['field'];
      if ($is_field && _redhen_dedupe_field_is_multivalue($name, $property)) {
        $merge_data['values'][$name] = array(
          '#type' => 'checkboxes',
          '#title' => filter_xss($property['label']),
          '#options' => array(),
        );
      }
      else {
        $merge_data['values'][$name] = array(
          '#type' => 'radios',
          '#title' => $property['label'],
          '#options' => array(),
        );
      }
      $options =& $merge_data['values'][$name]['#options'];

      // Loop through each contact to build a row element/radio button option:
      foreach ($contacts as $ent_id => $contact) {

        // We do some work to figure out what kind of field we are dealing with,
        // and set our values and displays appropriately. The important factors
        // are if it's a field or not, and whether it has a setter/getter
        // callback that we should be using.
        $in_bundle = isset($info['bundles'][$contact->type]['properties'][$name]);
        if (!$in_bundle && $is_field) {
          $options[$ent_id] = REDHEN_DEDUPE_NOT_APPLICABLE;
          continue;
        }

        // Set the default to match the Master record:
        if ($ent_id === $master_id) {
          $merge_data['values'][$name]['#default_value'] = $merge_data['values'][$name]['#type'] == 'radios' ? $ent_id : array(
            $ent_id,
          );
        }
        $options[$ent_id] = redhen_dedupe_option_label($contact, $name, $property);
      }
    }
  }

  // Exclude properties that are all the same from the merge form.
  foreach (element_children($merge_data['values']) as $name) {
    $left = array_unique($merge_data['values'][$name]['#options']);

    // Filter out any remaining items that are not applicable.
    $left = array_filter($left, function ($item) {
      return $item !== REDHEN_DEDUPE_NOT_APPLICABLE;
    });
    if (empty($left) || count($left) === 1) {
      unset($merge_data['values'][$name]);
      continue;
    }
  }
  $related_types = array();
  if (module_exists('redhen_note')) {
    $related_types['redhen_note'] = t('Notes');
  }
  if (module_exists('redhen_engagement')) {
    $related_types['redhen_engagement'] = t('Engagement Scores');
  }
  if (module_exists('redhen_membership')) {
    $related_types['redhen_membership'] = t('Memberships');
  }
  if (module_exists('redhen_relation')) {
    $related_types['relation'] = t('Relationships/Affiliations');
  }
  if (count($related_types) > 0) {
    $form['related_entities'] = array(
      '#type' => 'checkboxes',
      '#title' => t('Move items attached to old records to Master record:'),
      '#options' => $related_types,
      '#default_value' => array_keys($related_types),
    );
  }
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => t('Merge'),
  );
  return $form;
}