Programmatically create and update field collection item for the node with entity API

Field Collection is a handy module, that allows you to organize collections of fields into separate entities for reuse. I was working on a project that required migration of content from a typo3 CMS to the drupal CMS.

Some of the content types had field collection fields. I wrote a php script to do the migration, though there were tools like migrate module and typo3 migrate module. I decided to choose my own custom way because I wanted to get a greater experience and knowledge of Drupal 7's entity API for my future projects. I used the typo3 migrate module to migrate users data but did the other content migration by writing a php script.I may probably blog about the typo3 to drupal migration later with more details.

Now,field collections are separate entities, you can not just import the data into the node's fields. If you try to do so, an error will result, since the node itself does not have those fields - they belong to a field collection entity, and it is the field collection entity that belongs to a node. I had a though time dealing with that programmatically initially but found a solution which i want to share.

My first example shows the creation of a field collection entity that will be attached to a node that has a field collection field already defined for it.Let's assume the field collection field is field_collection1 attach to a node type. The example shows creating the field collection entity (using the entity_create function of the Entity API.

To attach or create field-collection item for node having node id say 16.


$node = node_load(16);
$field_collection_val = entity_create('field_collection_item', array('field_name' => 'field_collection1')); 

// Attach to the node
$field_collection_value->setHostEntity('node', $node); .

$field_collection_value->field_collection1[LANGUAGE_NONE][0]['value'] = 'your fetch data here/some data here'; 

// Save field-collection item.
$field_collection_value->save(); 



To modify/update (load/edit/save) values from existing field collection item of node having node id 16

$nid =16;
$node =node_load($nid);

// Get field collection item value.
$field_collection_item_value = $node->field_collection1[LANGUAGE_NONE][0]['value']; 

// Load that field collection item
$field_collection_value = entity_load('field_collection_item', array($field_collection_item_value)); 

$field_collection_value->field_collection1[LANGUAGE_NONE][0]['value'] = 'updated value here'; 

 // Save field-collection item.
$field_collection_value->save();


Note: You can use an Entity Wrapper provided by the Entity API module. Below is an example of updating a field collection field using the Entity wrapper.

$nid = 16;
$node = node_load($nid);

// Wrap it with Entity API
$node = entity_metadata_wrapper('node', $node);

$field_collection_value = $node->field_collection[0]->value();

// Wrap it with Entity API
$collection = entity_metadata_wrapper('field_collection_item', $field_collection_value);

//dsm the old value
dsm($collection->field_example->value()) //this dumps the old value contained in the field

// Set a new value on the field.
$collection->field_collection1 = 'New/updated value';

// Save the changes to the entity
$collection->save();

To delete existing field collection item.

$nid = 16;
$node = node_load($nid);

// Get field collection item value.
$field_collection_item_value = $node->field_collection1[LANGUAGE_NONE][0]['value']; 

 // Delete field collection item.
entity_delete_multiple('field_collection_item', array($field_collection_item_value));

For more documentation take a look at http://drupal.org/node/1842304.
Share