You are here

function entityreference_autofill_field_attach_form in Entity reference autofill 7

Implements hook_field_attach_form().

File

./entityreference_autofill.module, line 93
Entity reference autofill module.

Code

function entityreference_autofill_field_attach_form($entity_type, $entity, &$form, &$form_state, $langcode) {

  // Get info about current entity.
  list(, , $bundle) = entity_extract_ids($entity_type, $entity);

  // Get array of fields that have enabled autofill.
  $autofill_settings = _entityreference_autofill_get_settings();

  // No autofill references in this bundle.
  if (empty($autofill_settings[$entity_type][$bundle])) {
    return;
  }

  // Load settings from form_state.
  $autofill_bundle_settings = $autofill_settings[$entity_type][$bundle];

  // If an AJAX-call triggered this request,
  // use the triggering field's settings to autofill.
  $callback = isset($form_state['triggering_element']['#ajax']['callback']) ? $form_state['triggering_element']['#ajax']['callback'] : FALSE;
  if ($callback == 'entityreference_autofill_form_autofill') {
    $triggering_element = $form_state['triggering_element'];

    // @todo Ensure this is the base form containing the triggering element.
    $reference_field_parents = $triggering_element['#parents'];

    // Reset array pointers to ensure parent arrays are in sync.
    reset($reference_field_parents);
    reset($form['#parents']);
    foreach ($form['#parents'] as $parent) {
      if ($parent == current($reference_field_parents)) {
        array_shift($reference_field_parents);
      }
      else {
        return;
      }
    }
    if (!($element_info = drupal_array_get_nested_value($form, $reference_field_parents))) {
      return;
    }
    $reference_field_name = $element_info['#field_name'];

    // Add element info to form state.
    // @see entityreference_autofill_form_autofill().
    // @todo find alternative way to do this.
    $form_state['entityreference_autofill']['#element_info'] = $element_info;

    // Fill form with values from selected entity.
    if (!empty($autofill_bundle_settings[$reference_field_name]['fields'])) {
      $referenced_target_id = drupal_array_get_nested_value($form_state['values'], $triggering_element['#parents']);

      // Get field and instance info for triggering element.
      // @todo Fetch from form_state instead?
      // In that case, field collections - how?
      $context_field = array();
      $context_field['field'] = field_info_field($reference_field_name);
      if (isset($triggering_element['#entity_type'], $triggering_element['#bundle'])) {
        $context_field['instance'] = field_info_instance($triggering_element['#entity_type'], $reference_field_name, $triggering_element['#bundle']);
      }

      // For third-party widgets, reference target id might have to be fetched
      // from someplace else. Alter hook for module-specific customization.
      $context = array(
        'field_name' => $reference_field_name,
        'field' => $context_field,
        'form' => $form,
        'langcode' => $langcode,
      );
      drupal_alter('entityreference_autofill_target_id', $referenced_target_id, $form_state, $context);

      // Feeble attempt to support arbitrary widgets.
      // (For radio support).
      while (is_array($referenced_target_id)) {
        $referenced_target_id = isset($referenced_target_id['target_id']) ? $referenced_target_id['target_id'] : reset($referenced_target_id);
      }
      entityreference_autofill_populate_form_by_field($referenced_target_id, $reference_field_name, $langcode, $autofill_bundle_settings[$reference_field_name], $entity_type, $bundle, $form, $form_state);
    }
  }
  elseif (empty($form_state['input'])) {

    // Find all prepopulated reference fields in current bundle.
    foreach (array_keys($autofill_bundle_settings) as $reference_field_name) {

      // Check if field has default value.
      $language = field_language($entity_type, $entity, $reference_field_name, $langcode);
      if (empty($language)) {
        $language = LANGUAGE_NONE;
      }
      $field = field_info_field($reference_field_name);
      $instance = field_info_instance($entity_type, $reference_field_name, $bundle);
      $default_value = field_get_default_value($entity_type, $entity, $field, $instance, $language);

      // Fill form with referenced values.
      if (isset($default_value[0]['target_id'])) {
        $referenced_target_id = $default_value[0]['target_id'];
        entityreference_autofill_populate_form_by_field($referenced_target_id, $reference_field_name, $langcode, $autofill_bundle_settings[$reference_field_name], $entity_type, $bundle, $form, $form_state);
      }
    }
  }

  // Add autofill wrappers to enabled fields.
  foreach ($autofill_bundle_settings as $reference_field) {
    foreach ($reference_field['fields'] as $field_name) {
      $wrapper_id = _entityreference_autofill_get_wrapper($entity_type, $bundle, $field_name, $form['#parents']);
      $form[$field_name]['#prefix'] = '<div id="' . $wrapper_id . '" class="entityreference-autofill-field">';
      $form[$field_name]['#suffix'] = '</div>';
    }
  }
}