In Drupal 7, Field Collections are entities in themselves and they are attached to other entities like nodes, terms or users. So a content type like a node can have a field collection field, with multiple values if you like. There are many cases when this could fit your needs, but in this short article I would just like to highlight the technical details I learned from working with field collections.
First of all, the way they are stored. Each field collection is stored as a field collection item in the database. In the field table for the entity the field collection is attached to, only the field collection item ID is stored. Then the field collection has its own fields with their corresponding field tables. So the relationship in the database is as follows:
- The entity field stores the ID of the field collection item
- The 'field_collection_item' is keyed by this ID and stores the 'type' of field collection item. This 'type' is the name of the entity field the field collection item represents.
- The fields on the field collection items are stored in regular field data tables.
Then there is the question of how to create, load or save field collections programmatically.
Let's have a look at loading the field collection first:
// You can either load the field collection itself:
// or load it through its host entity, e.g. a node:
$node = node_load($node_id);
$entity_metadata_wrapper = entity_metadata_wrapper('node', $node);
$field_collection_item = $entity_metadata_wrapper->my_field_collection->value();
// and then get the host entity again from the field collection item:
$node = $field_collection_item->hostEntity();
// or even get the field values from the field collection item:
$entity_metadata_wrapper = entity_metadata_wrapper('field_collection_item', $field_collection_item);
$field_value = $entity_metadata_wrapper->my_field_collection_item_field->value();
Now let's have a look at creating a new field collection item and attaching it to an entity, like - how surprising - a node:
// New field collection item:
// Keep in mind that the field collection itself must already have been defined!
$values = array('field_name' => 'my_field_collection');
$new_field_collection_item = entity_create('field_collection_item', $values);
// Then attach it to a node. Alternatively, this can also be a term or a user or a different entity.
$node = node_load($node_id); // it needs to be the node object.
//Then save everyting:
// Note that both the field collection item and the host entity must be saved!
Well, if you're a developer and you're using field collection items, I hope this snippet is useful!