4

I'm trying to programmatically set a value on a field collection item attached to the user entity.

The field collection field in question is titled, field_user_location.

I initially had this ($usr_wrapper being an entity metadata wrapper of the user entity)

$usr_wrapper->field_user_location->field_land_phone->set($object['Phone Number']);

However that doesn't appear to work.

How do you get data onto a field collection via entity_metadata_wrapper()? There isn't much documentation about how to do this that I am seeing.

2 Answers 2

4

I found the documentation for field collections confusing as well.

Field collections need their own entity metadata wrapper. So, the following code would work for your example:

$collection = entity_create('field_collection_item', array('field_name' => 'field_user_location'));
$collection->setHostEntity('user', $user);
$fc_wrapper = entity_metadata_wrapper('field_collection_item', $collection);
$fc_wrapper->field_land_phone->set($object['Phone Number']);

I hope that helps for anyone else banging their heads over this.

2
  • Just for clarification, what is $object? Just a newly-instatiated array named 'object'?
    – user1359
    Commented Aug 19, 2015 at 20:04
  • In this example, we don't know exactly what $object was. We only know that it was an array that had a key named 'Phone Number'. The important thing as far as entity metadata wrappers are concerned is that the set method receives an argument that matches the data structure of the field to which it's attached. So, if the field_land_phone is a textfield that holds a string value, you pass it the string you want to set it to. That line could just have easily read $fc_wrapper->field_land_phone->set('867-5309');
    – a-fro
    Commented Aug 20, 2015 at 11:35
0

Based on your example, the could should be:

global $user;
$usr_wrapper = entity_metadata_wrapper('user', $user);

// Create the collection entity and set its "host".
$field_collection_item = entity_create('field_collection_item', array('field_name' => 'field_user_location')); // Name of collection field.
$field_collection_item->setHostEntity('node', $usr_wrapper->value());

// Now define the collection parameters.
$collection = entity_metadata_wrapper('field_collection_item', $field_collection_item);
$collection->field_land_phone = "0123"; // array("0123") in case of multi-valued field.
// $collection->field_land_phone->set("0123"); // Version using set(), use: set(array("0123")) for multi-valued field.

// Save.
$collection->save(); // Or: $usr_wrapper->save();

Also check Entity metadata wrappers documentation page (check for Example using field collections).


Here is another example which adds an entry to a node with a field collection named field_activity_log:

  // Load the controller class file.
  module_load_include('inc', 'entity', 'includes/entity.controller');

  // Use the currently logged in user if a $uid argument is not defined.
  global $user;
  if (empty($uid)) {
    $uid = $user->uid;
  }

  $now = gmdate('Y-m-d H:i:s'); // Grab the current time.

  // Setup the values in the structure expected by the field_collection entity.
  $values = array(
    'field_name' => 'field_activity_log',
    'field_activity_log_date' => array(
      LANGUAGE_NONE => array(array('value' => $now)),
    ),
    'field_activity_log_message' => array(
      LANGUAGE_NONE => array(array('value' => $message)),
    ),
    'field_activity_log_user' => array(
      LANGUAGE_NONE => array(array('uid' => $uid)),
    ),
  );
  $entity = entity_create('field_collection_item', $values);

  // Attach the field_collection entity to the application node. This has to
  // happen separately so that it actually works -- you can't just specify
  // this via the $values array.
  $entity->setHostEntity('node', $node);

  // Save the entity. Since it's attached to the right application node, this
  // will both create the field_collection entity and update the application
  // node to point to the new field_activity_log record.
  $entity->save();
?>

Source: Example: Programmatically adding field collection entries to a node

And this example shows updating (loading/editing/saving) an existing field collection in an Entity Wrapper:

<?php
// 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();
?>

Source: Example: Programmatically create and update field collection with Entity API


Troubleshooting

In case of error when setting the data value with set(), be be sure it matches the required data type and format. If your entity won't get saved, check for the logs for any wrapper exceptions (drush ws --tail).

See also: Modifying a field collection programmatically missing hostEntity fields at SO

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.