function field_collection_field_widget_form in Field collection 7
Implements hook_field_widget_form().
File
- ./
field_collection.module, line 1239 - Module implementing field collection field type.
Code
function field_collection_field_widget_form(&$form, &$form_state, $field, $instance, $langcode, $items, $delta, $element) {
static $recursion = 0;
switch ($instance['widget']['type']) {
case 'field_collection_hidden':
return $element;
case 'field_collection_embed':
// If the field collection item form contains another field collection,
// we might ran into a recursive loop. Prevent that.
if ($recursion++ > 3) {
drupal_set_message(t('The field collection item form has not been embedded to avoid recursive loops.'), 'error');
return $element;
}
$field_parents = $element['#field_parents'];
$field_name = $element['#field_name'];
$language = $element['#language'];
// Nest the field collection item entity form in a dedicated parent space,
// by appending [field_name, langcode, delta] to the current parent space.
// That way the form values of the field collection item are separated.
$parents = array_merge($field_parents, array(
$field_name,
$language,
$delta,
));
$element += array(
'#element_validate' => array(
'field_collection_field_widget_embed_validate',
),
'#parents' => $parents,
);
if ($field['cardinality'] == 1) {
$element['#type'] = 'fieldset';
}
$field_state = field_form_get_state($field_parents, $field_name, $language, $form_state);
if ($delta > 0 && $delta == $field_state['items_count'] && field_collection_hide_blank_items($field)) {
// Do not add a blank item. Also see
// field_collection_field_attach_form() for correcting #max_delta.
$recursion--;
return FALSE;
}
if ($field_state['items_count'] == 0 && field_collection_hide_blank_items($field)) {
// We show one item, so also specify that as item count. So when the
// add button is pressed the item count will be 2 and we show two items.
$field_state['items_count'] = 1;
}
if (isset($field_state['entity'][$delta])) {
$field_collection_item = $field_state['entity'][$delta];
}
else {
if (isset($items[$delta])) {
$field_collection_item = field_collection_field_get_entity($items[$delta], $field_name);
}
// Show an empty collection if we have no existing one or it does not
// load.
if (empty($field_collection_item)) {
$field_collection_item = entity_create('field_collection_item', array(
'field_name' => $field_name,
));
$field_collection_item
->setHostEntity($element['#entity_type'], $element['#entity'], $langcode);
}
// Put our entity in the form state, so FAPI callbacks can access it.
$field_state['entity'][$delta] = $field_collection_item;
}
// Register a child entity translation handler to properly deal with the
// entity form language.
if (field_collection_item_is_translatable()) {
$element['#host_entity_type'] = $element['#entity_type'];
$element['#host_entity'] = $element['#entity'];
// Give each field collection item a unique entity translation handler
// ID, otherwise an infinite loop occurs when adding values to nested
// field collection items.
if (!isset($field_collection_item->entity_translation_handler_id)) {
list($id, $revision_id) = entity_extract_ids('field_collection_item', $field_collection_item);
$revision_id = isset($revision_id) ? $revision_id : 0;
$field_collection_item->entity_translation_handler_id = 'field_collection_item' . '-' . (!empty($id) ? 'eid-' . $id . '-' . $revision_id : 'new-' . mt_rand());
}
$element['#field_collection_item'] = $field_collection_item;
field_collection_add_child_translation_handler($element);
// Ensure this is executed even with cached forms. This is mainly useful
// when dealing with AJAX calls.
$element['#process'][] = 'field_collection_add_child_translation_handler';
// Flag the field to be processed in field_collection_form_alter to
// avoid adding incorrect translation hints.
$address = array_slice($element['#parents'], 0, -2);
if (empty($form['#field_collection_translation_fields']) || !in_array($address, $form['#field_collection_translation_fields'])) {
$form['#field_collection_translation_fields'][] = $address;
}
}
// Add the subform.
field_form_set_state($field_parents, $field_name, $language, $form_state, $field_state);
// Set the language to to parent entity language, because
// field_content_languages() will always set $language to LANGUAGE_NONE.
if (field_collection_item_is_translatable()) {
field_attach_form('field_collection_item', $field_collection_item, $element, $form_state, entity_language($element['#host_entity_type'], $element['#host_entity']));
}
else {
field_attach_form('field_collection_item', $field_collection_item, $element, $form_state, $language);
}
// Make sure subfields get translatable clues (like 'all languages')
if (field_collection_item_is_translatable() && variable_get('entity_translation_shared_labels', TRUE)) {
foreach (element_children($element) as $key) {
$element[$key]['#process'][] = 'entity_translation_element_translatability_clue';
}
}
if (empty($element['#required'])) {
$element['#after_build'][] = 'field_collection_field_widget_embed_delay_required_validation';
}
if ($field['cardinality'] == FIELD_CARDINALITY_UNLIMITED && empty($form_state['programmed'])) {
$element['remove_button'] = array(
'#delta' => $delta,
'#name' => implode('_', $parents) . '_remove_button',
'#type' => 'submit',
'#value' => t('Remove'),
'#validate' => array(),
'#submit' => array(
'field_collection_remove_submit',
),
'#attributes' => array(
'class' => array(
'remove-button',
),
),
'#limit_validation_errors' => array(),
'#ajax' => array(
// 'wrapper' is filled in field_collection_field_attach_form().
'callback' => 'field_collection_remove_js',
'effect' => 'fade',
),
'#weight' => 1000,
);
}
$recursion--;
return $element;
case 'field_collection_sorter':
$elements = array();
$field_name = $field['field_name'];
$parents = $form['#parents'];
$field_state = field_form_get_state($parents, $field_name, $langcode, $form_state);
$count = $field_state['items_count'];
for ($delta = 0; $delta < $count; $delta++) {
$item_id = isset($items[$delta]['value']) ? $items[$delta]['value'] : NULL;
$revision_id = isset($items[$delta]['revision_id']) ? $items[$delta]['revision_id'] : NULL;
// Add a label component to visually identify this field collection item.
$element['label'] = array();
if ($item_id) {
$item = field_collection_item_load($item_id);
$element['label']['#markup'] = $item ? $item
->label() : $item_id;
}
// The field stored value (item_id) and revision_id values so we need
// hidden fields to represent them.
$element['value'] = array(
'#type' => 'hidden',
'#default_value' => $item_id,
);
$element['revision_id'] = array(
'#type' => 'hidden',
'#default_value' => $revision_id,
);
// Input field for the delta (drag-n-drop reordering).
// We name the element '_weight' to avoid clashing with elements
// defined by widget.
$element['_weight'] = array(
'#type' => 'weight',
'#title' => t('Weight for row @number', array(
'@number' => $delta + 1,
)),
'#title_display' => 'invisible',
// Note: this 'delta' is the FAPI 'weight' element's property.
'#delta' => $count,
'#default_value' => isset($items[$delta]['_weight']) ? $items[$delta]['_weight'] : $delta,
'#weight' => 100,
);
$elements[$delta] = $element;
}
if ($elements) {
$elements += array(
'#theme' => 'field_multiple_value_form',
'#field_name' => $field['field_name'],
'#cardinality' => $field['cardinality'],
'#title' => check_plain($instance['label']),
'#required' => FALSE,
'#description' => field_filter_xss($instance['description']),
'#max_delta' => $count - 1,
);
}
return $elements;
}
}