Entities and attached fields: how to get the form array for the fields

Matthias Weiss's picture
Matthias Weiss

There are times when you want to display parts of an entity to the user, pariticularily a specific list of fields that are attached (bundled) to that entity. Core doesn't offer functionality for this so I'll show you a simple function for extracting the form array structure for a selectable list of fields of an entity.

The function takes the entity type (e.g. 'node' or 'user') as first argument, the object of the entity for which you want to get the field forms as 2nd field and an array of field names (machine names) as 3rd argument and an optional language code as 4th.



function get_entity_field_form($entity_type, &$entity, $field_names, $langcode = NULL) {

  $field_forms = array('#parents' => array());

  // copied from form.inc: drupal_build_form
  $form_state = form_state_defaults();

  if (!isset($form_state['input'])) {
    $form_state['input'] = $form_state['method'] == 'get' ? $_GET : $_POST;
  }

  // copied from field.attach.inc: field_attach_form
  $options               = array('language' => field_valid_language($langcode));
  $available_field_forms = (array) _field_invoke_default('form', $entity_type, $entity, $field_forms, $form_state, $options);

  foreach ($field_names as $field) {
    if (isset($available_field_forms[$field]) == TRUE) {
      $field_forms[$field] = &$available_field_forms[$field];
    }
  }

  // copied from field.attach.inc: field_attach_form
  $entity_ids                   = entity_extract_ids($entity_type, $entity);
  $field_forms['#pre_render'][] = '_field_extra_fields_pre_render';
  $field_forms['#entity_type']  = $entity_type;
  $field_forms['#bundle']       = $entity_ids[2];

  return $field_forms;
}

 

So you would use this function like

 

$node = node_load(17);

$form = get_entity_field_form('node', $node, array('field_data_body', 'field_data_'));