The Entity API provides classes and methods / functions that make CRUD for entities much, much easier and less prone to errors and bugs.
The 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 through the Manage Fields tab of the node type creation / modification UI. The example shows creating the field collection entity (using the entity_create function of the Entity API, attaching it to a node, and using the Entity API then to set values of fields within the field collection.
<?php
// Code that would be here but is omitted loads a node called $my_node
// Nodes of the type that is $my_node have a field of the field collection
// type called field_text_files, which in turn is defined as having two
// fields called field_source_txt_filename and field_source_txt_content
// Begin by using the entity_create function to create a new entity of
// type field_collection_item. The second parameter to the function
// provides "an array of values to set, keyed by property name".
// In our example, the field in my_node that holds the field collection is
// the field_text_files field.
$fc_item = entity_create('field_collection_item', array('field_name' => 'field_text_files'));
// Now connect / attach the new field collection item to a node that
// we loaded earlier in our code and stored in the $my_node variable.
// The setHostEntity function is provided by the Field Collection module.
$fc_item->setHostEntity('node', $my_node);
// Now, we use the entity_metadata_wrapper function from the Entity
// API to "wrap" the field collection entity in a class that simplifies
// working with the entity.
$fc_wrapper = entity_metadata_wrapper('field_collection_item', $fc_item);
// If we weren't using the entity_metadata_wrapper function, we'd have to
// access and set field values within the field collection entity using this code:
//
// $fc_item->field_source_txt_filename[LANGUAGE_NONE][0]['value'] = $stat['name'];
//
// This code is obviously less readable and also not as friendly to translations
// perhaps.
// Now, we just put a string value into a field on the field collection entity
// The set() method appears to be the preferred way to set values on
// entity fields, as opposed doing an assignment of data to the value() property
$fc_wrapper->field_source_txt_filename->set('my_text_file.txt');
// Put another string value into another field on the field collection entity
$txt_file_content = "A whole bunch of content.";
$fc_wrapper->field_source_txt_content->set($txt_file_content);
// Now save the node
node_save($my_node);
// As an alternative to node_save, you could use
// field_attach_update('node', $my_node);
// This function from the Field API saves field data for an existing entity but
// doesn't save the entity itself. So, in the code above, the field_text_files field
// that belongs to $my_node would get saved, but the $my_node node would
// not get saved.
?>
References for functions and methods used in the example above:
- setHostEntity at drupalcommerce.org
- entity_metadata_wrapper on drupalcontrib.org
- LevelTen Tutorial from leveltendesign.com
- Documentation for entity metadata wrappers from drupal.org
- field_attach_update documentation from api.drupal.org
This example shows updating (loading/editing/saving) an existing field collection in an Entity Wrapper provided by the Entity API module.
// Load the node by NID
$raw_node = node_load($nid);
// Wrap it with Entity API
$node = entity_metadata_wrapper('node', $raw_node);
// Get the first item from the muli-value field collection
$raw_collection = $node->field_collection->value();
// Wrap it with Entity API
$collection = entity_metadata_wrapper('field_collection_item', $raw_collection);
//dsm the old value
dsm($collection->field_example->value());
// Set a new value on the field_example textfield.
$collection->field_example = 'New value';
// Save the changes to the entity
$collection->save();
Comments
Small error in the update script
I was getting this error "field_collection Cannot use object of type EntityDrupalWrapper as array"
I just changed the line
$raw_collection = $node->field_personal_information[0]->value();
to this
$raw_collection = $node->field_personal_information->value();
and now it is working fine.
thank you
Regards,
Sumaiya Javed
Web Developer
www.sumaiyajaved.com
www.phpjavascript.com
Strange error
When I update/delete a fc, It returns "Illegal offset type in unset" error in .../field_collection/field_collection.module, line 1013. Any idea?
Adding Multiple Field Collections at once
What would be the best way to add multiple field collections at once?
I could iterate through those 8 lines repeatedly, but multiple node_save() commands didn't seem very efficient.
@cmarcera,
@cmarcera,
I have no idea if my case is similar to yours, but I also needed to insert multiple field collections while creating new users programmatically on a Drupal 7 site.
I have a category Jobs added to users like Drupal 6 Profile categories(using module user_categories). There is a field collection field_joining under category Jobs with fields, field_joining_job, field_joining_date and field_resigning_date. A user can enter many values for this field collection. I have to do the following to insert more than one set of values:
Repeat the following code as many times as many values you need to insert.
Hope it helps..