You are here

function field_collection_field_widget_embed_validate in Field collection 7

FAPI validation of an individual field collection element.

1 string reference to 'field_collection_field_widget_embed_validate'
field_collection_field_widget_form in ./field_collection.module
Implements hook_field_widget_form().

File

./field_collection.module, line 1744
Module implementing field collection field type.

Code

function field_collection_field_widget_embed_validate($element, &$form_state, $complete_form) {
  $field = field_widget_field($element, $form_state);
  $field_parents = $element['#field_parents'];
  $field_name = $element['#field_name'];
  $language = $element['#language'];
  $field_state = field_form_get_state($field_parents, $field_name, $language, $form_state);

  // We have to populate the field_collection_item before we can attach it to
  // the form.
  if (isset($field_state['entity'][$element['#delta']])) {
    $field_collection_item = $field_state['entity'][$element['#delta']];
  }
  else {
    $field_values = drupal_array_get_nested_value($form_state['values'], $field_state['array_parents']);
    if ($field_values[$element['#delta']]) {
      $field_collection_item = entity_create('field_collection_item', array(
        'field_name' => $field['field_name'],
      ));
      foreach ($field_values[$element['#delta']] as $key => $value) {
        if (property_exists($field_collection_item, $key)) {
          $field_collection_item->{$key} = $value;
        }
      }
    }
  }

  // Attach field API validation of the embedded form.
  field_attach_form_validate('field_collection_item', $field_collection_item, $element, $form_state);

  // Handle a possible language change.
  if (field_collection_item_is_translatable()) {
    $handler = entity_translation_get_handler('field_collection_item', $field_collection_item);
    $element_values =& drupal_array_get_nested_value($form_state['values'], $field_state['array_parents']);
    $element_form_state = array(
      'values' => &$element_values[$element['#delta']],
    );
    $handler
      ->entityFormLanguageWidgetSubmit($element, $element_form_state);
  }

  // Now validate required elements if the entity is not empty.
  if (!empty($element['#field_collection_required_elements']) && !field_collection_item_is_empty($field_collection_item)) {
    foreach ($element['#field_collection_required_elements'] as &$elements) {

      // Copied from _form_validate().
      if (isset($elements['#needs_validation'])) {
        $is_countable = is_array($elements['#value']) || $elements['#value'] instanceof Countable;
        $is_empty_multiple = $is_countable && !count($elements['#value']);
        $is_empty_string = is_string($elements['#value']) && drupal_strlen(trim($elements['#value'])) == 0;
        $is_empty_value = $elements['#value'] === 0;
        $is_empty_option = isset($elements['#options']['_none']) && $elements['#value'] === '_none';

        // Validate fields with hook_field_is_empty. This will handle cases when
        // file entity passes validation when it shouldn't.
        $is_empty_field = FALSE;
        if (isset($elements['#field_name'])) {
          $field = field_info_field($elements['#field_name']);

          // Extract field values array with all columns from form_state.
          // The field we're looking at is always 3 levels deeper than field
          // collection field.
          $field_depth = count($elements['#field_parents']) + 3;
          $field_values = drupal_array_get_nested_value($form_state['values'], array_slice($elements['#array_parents'], 0, $field_depth));

          // Special case lists since we don't get the correct array_parents.
          if (is_array($field_values) && count($elements['#array_parents']) < $field_depth) {
            $field_values = reset($field_values);
          }
          $is_empty_field = module_invoke($field['module'], 'field_is_empty', $field_values, $field);
        }
        if ($is_empty_multiple || $is_empty_string || $is_empty_value || $is_empty_option || $is_empty_field) {
          if (isset($elements['#title'])) {
            form_error($elements, t('@name field is required in the @collection collection.', array(
              '@name' => $elements['#title'],
              '@collection' => $field_state['instance']['label'],
            )));
          }
          else {
            form_error($elements);
          }
        }
      }
    }
  }

  // Only if the form is being submitted, finish the collection entity and
  // prepare it for saving.
  if ($form_state['submitted'] && !form_get_error($element)) {
    field_attach_submit('field_collection_item', $field_collection_item, $element, $form_state);

    // Load initial form values into $item, so any other form values below the
    // same parents are kept.
    $item = drupal_array_get_nested_value($form_state['values'], $element['#parents']);

    // Set the _weight if it is a multiple field.
    if (isset($element['_weight']) && ($field['cardinality'] > 1 || $field['cardinality'] == FIELD_CARDINALITY_UNLIMITED)) {
      $item['_weight'] = $element['_weight']['#value'];
    }

    // Ensure field columns are poroperly populated.
    $item['value'] = $field_collection_item->item_id;
    $item['revision_id'] = $field_collection_item->revision_id;

    // Put the field collection item in $item['entity'], so it is saved with
    // the host entity via hook_field_presave() / field API if it is not empty.
    // @see field_collection_field_presave()
    $item['entity'] = $field_collection_item;
    form_set_value($element, $item, $form_state);
  }
}