Save/update field collection without node_save

Posted on 30 Nov 2012 by Oleksii Raiu
Some sites are quite complex. And some complex sites also have complex pages. A good way to group data on those pages is to use Field Collection module. Field Collection module utilizes Drupal 7's entity interface to store your field collection as an entity, rather than a field directly attached to your node. The benefit is obvious - you can manage little 'sub-nodes' for your node, like company's houses, or person's quotes, without having to create a whole new node for them. And for multi-value field groups, it's just a prodigy! You simply create a field collection entity, and then you add fields to it, rather than to a node. Programmatically, field collections can be handled via standard entity_load() and entity_save(). However, there are two ways to save a field collection. Field collection interface needs to know, whether you are saving a new, or updating an existing field collection entity, and whether it's reference to the parent entity (node or other field collection holding it) has changed. When saving field collections, you can evade updating the node and save time, by using the field collection's save() function. It is an extension of Field Collection entity, that allows you to pass a parameter with the save() function, telling it to skip node update. Say, you fave an entity, $fc, which is a field collection. You can do $fc->save(TRUE), if all you need is to update an existing field collection. Saves time in batch scripts. Though every case is special, the overall flow will look something like this:

// Get field collection (supposedly containing one image with meta data)
$fc = entity_load('field_collection_item', array($fcid));
// If we were to have multi-value fc's, we weould have a cycle here in place of current()
$fc = current($fc);

// Get meta data. A custom function.
$meta = custom_get_meta_data($fc);

// Assign meta data
$fc->field_title[LANGUAGE_NONE][0]['value'] = $meta->title;
$fc->field_author_name[LANGUAGE_NONE][0]['value'] = $meta->author;
$fc->field_caption[LANGUAGE_NONE][0]['value'] = $meta->caption;
$fc->field_alt_text[LANGUAGE_NONE][0]['value'] = $meta->alt_text;
$fc->field_short_caption[LANGUAGE_NONE][0]['value'] = $meta->short_caption;

entity_save('field_collection_item', $fc);