When a new field collection is created and attached to its host, it cannot be accessed via a EntityListWrapper until it have been saved.

This change coupled with #1587882: Allow getter callbaks to provide lists of entity objects allows for the EntityListWrapper to access a list with both ids and entities making it much easier to manage field collections before they are saved.

Also when you have multiple new field collections there is a bug in which the field language is returned as 0 unstead of (normally) und. This is fixed in #1587874: field_language() caching to strict when creating multiple new entity types with different bundles.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

geek-merlin’s picture

Status: Needs review » Needs work

current source tells us that this is fixed for single value fields but needs a fix in the wrapper for multiple valued ones.

Wrappers do not support multiple entity references being revisions or not yet saved entities.

did not check that though.
would be great to have.

/**
 * Entity property info getter callback for the field collection items.
 *
 * Like entity_metadata_field_property_get(), but additionally supports getting
 * not-yet saved collection items from @code $item['entity'] @endcode.
 */
function field_collection_field_property_get($entity, array $options, $name, $entity_type, $info) {
  $field = field_info_field($name);
  $langcode = field_language($entity_type, $entity, $name, isset($options['language']) ? $options['language']->language : NULL);
  $values = array();
  if (isset($entity->{$name}[$langcode])) {
    foreach ($entity->{$name}[$langcode] as $delta => $data) {
      // Wrappers do not support multiple entity references being revisions or
      // not yet saved entities. In the case of a single reference we can return
      // the entity object though.
      if ($field['cardinality'] == 1) {
        $values[$delta] = field_collection_field_get_entity($data);
      }
      elseif (isset($data['value'])) {
        $values[$delta] = $data['value'];
      }
    }
  }
  // For an empty single-valued field, we have to return NULL.
  return $field['cardinality'] == 1 ? ($values ? reset($values) : NULL) : $values;
}

geek-merlin’s picture

Status: Needs work » Needs review

patch_commit_7703becd22b5.patch queued for re-testing.

Jelle_S’s picture

Issue summary: View changes
FileSize
562 bytes

While we wait for #1587882: Allow getter callbaks to provide lists of entity objects to get committed, we could already fix the issue where metadata wrappers do not work on multi-value field collection items in hook_entity_presave

Steps to reproduce:

  1. Add a multi-value field collection to an entity type
  2. Create an entity of this type with values in the field collection field.
  3. Create a module with a presave hook. Pseudo code:
    /**
     * Implements hook_entity_presave().
     */
    function mymodule_entity_presave($entity, $entity_type) {
      if ($entity_type == 'my_entity_type') {
        $wrapped = entity_metadata_wrapper($entity_type, $entity);
        dpm($wrapped->field_my_field_collection->value());
      }
    }
    
  4. The dpm will output an empty array even though the field has multiple values.

Status: Needs review » Needs work

The last submitted patch, 3: i1587888-3.patch, failed testing.

Jelle_S’s picture

Version: 7.x-1.0-beta3 » 7.x-1.x-dev

Status: Needs work » Needs review

Jelle_S queued 3: i1587888-3.patch for re-testing.

Jelle_S queued 3: i1587888-3.patch for re-testing.

RoSk0’s picture

Patch to implement requested functionality. Depends on #1587882: Allow getter callbaks to provide lists of entity objects.