Let’s say you have a content type, containing a Field Collection which itself contains an Addressfield and you have to create the node programmatically. Complicated enough? Just imagine the rest of the content type I’ve got here! Below is how to do it without spending hours sailing the seas of che… PHP Exceptions.

You may have learned in Programmatically creating nodes using Entity Wrapper about the benefits of using EntityWrapper when working with Entities in Drupal. EntityWrapper greatly reduces the complexity of working with Entities in Drupal. You don’t have to type [LANGUAGE_NONE][0] anymore, unless the fields really are multi-lingual.

I’ll start with the easier example; an Addressfield in a node without a Field Collection.

  // Create an Entity with wrapper
  $node = entity_create('node', array('type' => 'person'));
  $entity = entity_metadata_wrapper('node',  $node);

  // Add a node title
  $entity->title = $person['name'];

  // Add the address information
  $entity->field_person_address->thoroughfare = $person['address'];
  $entity->field_person_address->locality = $person['city'];
  $entity->field_person_address->administrative_area = $person['state'];
  $entity->field_person_address->postal_code = $person['postalcode'];
  $entity->field_person_address->country = $person['country'];

  // Save the entity
  $entity->save();

Note: The above Addressfield related code currently produces a warning http://drupal.org/node/1764052 but still works.

Now the more complex example, a node containing a Field Collection containing an Addressfied.

  // Create an Entity with wrapper
  $node = entity_create('node', array('type' => 'person'));
  $entity = entity_metadata_wrapper('node',  $node);

  // Add a node title
  $entity->title = $person['name'];

  // Create a person address Field Collection Entity
  $address_raw = entity_create('field_collection_item', array('field_name' => 'field_person_address'));
  // Attach to the node. Note: $node, not $entity.
  $address_raw->setHostEntity('node', $node);

  // Wrap new collection in Entity API
  $address = entity_metadata_wrapper('field_collection_item', $address_raw);

  // Add the address information to the
  $address->field_person_addressfield->thoroughfare = $person['address'];
  $address->field_person_addressfield->locality = $person['city'];
  $address->field_person_addressfield->administrative_area = $person['state'];
  $address->field_person_addressfield->postal_code = $person['postalcode'];
  $address->field_person_addressfield->country = $person['country'];

  // Save the field collection
  $address->save();

  // Save the entity
  $entity->save();

You may ask why not just a multi-value field? I’ve got to store additional data with each address in my use case. This example is simplified.

Comments

(Statically copied from previous site)

Andi replied on December 16, 2016 - 1:22pm

Hmm, can’t get this second example to work no matter what I try….

brad replied on January 13, 2017 - 2:01pm

I wrote this four years ago. It should still work, but I haven’t tested this in a long time.