1

I have a field collection that contains several other fields (text and taxonomy reference) for collecting and unlimited number of addresses. I have added this field collection to user profiles. This is for a custom e-commerce site, where users may also enter new addresses during the checkout process. So, I need to be able to add values to this field collection during the checkout process (not just within the user's profile). I have tried a 1/2 dozen examples out there, but, all of the available examples are for adding values to a field collection that is attached to a NODE, not to a USER. I've replaced the NODE code with USER code, but, I get errors when I run it. Here is the latest that I tried:

module_load_include('inc', 'entity', 'includes/entity.controller');
global $user;

// Setup the values in the structure expected by the field_collection entity.
$values = array(
  'field_cnm_address_fname' => array(
    'und' => array(array('value' => $address['fname'])),
  ),
  'field_cnm_address_lname' => array(
    'und' => array(array('value' => $address['lname'])),
  ),
  'field_cnm_address_street1' => array(
    'und' => array(array('value' => $address['street1'])),
  ),
  …etc.
);

//This line added via MrD's suggestion.
$values['field_name'] = 'field_cnm_address';   // field collection name.

$entity = entity_create('field_collection_item', $values);
$entity->setHostEntity('user', $user); 
$result = $entity->save();

The error that I am getting is "Fatal error: Cannot access empty property in /.../sites/all/modules/field_collection/field_collection.module on line 326" which shows the line:

//(field_collection.module, line 326)
$entity->{$this->field_name}[$this->langcode][] = array('entity' => $this);

So, I'm thinking it does not recognize the host entity that I'm setting with setHostEntity()? I have added debugging output after each line of execution and can clearly see that it is failing at this line in my code:

$entity->setHostEntity('user', $user);

Any help or suggestions?

edit 1: I added the field_name to the array as suggested, and, now the address is added without error. However, when I try to access the value now in the same way I had previously, I get a new error:

$wrapper = entity_metadata_wrapper('user', $user);
foreach ($wrapper->field_cnm_address as $a){
  $country_term_obj = $a->field_cnm_address_country->value();
  //the above line using ->value() returns this error: 
  //Fatal error: Call to a member function value() on a non-object
}

Prior to programmatically adding values, the ->value() function worked fine, it would return a taxonomy term object. When adding values to the field non-programmatically (via the user profile interface with the field collection that contains the taxonomy reference field), ->value() would return a fully functioning object.

edit 2: Also, I have set this field collection to allow unlimited values. And, after programmatically adding to it's values, it appears that the "unlimited" feature has disappeared (the "add another" and "remove" buttons are gone on the user profile page).

edit 3: Ok sorry, ignore the above 2 edits. I see what's happening. The values that I'm adding via the code above is actually replacing the value that already exists in those fields for that user. Since this is a "unlimited" field collection, I'd like to be able to add another, versus replacing what's already been entered into those fields. Any idea how to do that?

edit 4: I've tried MrD's suggestion below for "Creat new multi value", However, now I have an error when trying to add a taxonomy term tid (my "field_country" field in this field collection is a term reference field). For example:

$values[0]['field_country'][LANGUAGE_NONE][0]['tid'] = 123;

Error output is:

Notice: Undefined property: stdClass::$name in taxonomy_term_save() (line 628 of /.../modules/taxonomy/taxonomy.module).
Notice: Undefined property: stdClass::$vid in taxonomy_term_save() (line 630 of /.../modules/taxonomy/taxonomy.module).
Warning: array_flip(): Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->load() (line 175 of /.../includes/entity.inc).
Warning: array_flip(): Can only flip STRING and INTEGER values! in DrupalDefaultEntityController->cacheGet() (line 354 of /.../includes/entity.inc).
Notice: Trying to get property of non-object in taxonomy_term_save() (line 631 of /.../modules/taxonomy/taxonomy.module).
EntityMalformedException: Missing bundle property on entity of type taxonomy_term. in entity_extract_ids() (line 7818 of /.../includes/common.inc).

It appears to be trying to save a taxonomy term. However, I am trying to assign an existing taxonomy term tid to the field, not save a new term. Any ideas?

1 Answer 1

1

You can try this

Creat new one field

  global $user;
  $values = array();
  // I think you missing field name of field collection.
  $values['field_name'] = 'field_address';   // field collection name.
  $values['field_field_name'][LANGUAGE_NONE][0]['value'] = 'Mr';
  $values['field_last_name'][LANGUAGE_NONE][0]['value'] = 'D';
  $values['field_street'][LANGUAGE_NONE][0]['value'] = 'Vietnamese';
  $field_entity = entity_create('field_collection_item', $values);
  $field_entity->setHostEntity('user', $user);
  $field_entity->save();

Creat new multi value

global $user;
  $values = array();
  $values[0]['field_name'] = 'field_address'; // field collection name
  $values[0]['field_field_name'][LANGUAGE_NONE][0]['value'] = 'Mr 0';
  $values[0]['field_last_name'][LANGUAGE_NONE][0]['value'] = 'D 0';
  $values[0]['field_street'][LANGUAGE_NONE][0]['value'] = 'Ha Noi 0';
  $values[1]['field_name'] = 'field_address'; // field collection name
  $values[1]['field_field_name'][LANGUAGE_NONE][0]['value'] = 'Mr 1';
  $values[1]['field_last_name'][LANGUAGE_NONE][0]['value'] = 'D 1';
  $values[1]['field_street'][LANGUAGE_NONE][0]['value'] = 'Ha Noi 1';
  foreach ($values as $key => $value) {
    $field_entity = entity_create('field_collection_item', $value);
    $field_entity->setHostEntity('user', $user);
    $field_entity->save();
  }

Note

  $field_entity->setHostEntity('user', $user);

this line auto save data to field collections and save data to user. You don't need to do anything.

Update Field

global $user;
// User need load user to get ids of field collections
$user = user_load($user->uid);
$array_ids = field_get_items('user', $user, 'field_address');
foreach ($array_ids as $key => $id) {
  $data = field_collection_item_load($id['value']);
  $wrapper = entity_metadata_wrapper('field_collection_item', $data);
  //Update value
  $wrapper->field_field_name->set('First Name');
  $wrapper->field_last_name->set('Last Name');
  $wrapper->field_street->set('Street');
  //Save value to field
  $wrapper->save();
}
4
  • Thank you! This is progress. The address was saved. However, now when I try to access the value, however, I get errors. Just realized I can't post code in a comment.
    – Cheryl
    Commented Jul 28, 2015 at 19:08
  • I added an "edit" to my above post to explain the new error.
    – Cheryl
    Commented Jul 28, 2015 at 19:13
  • See my update answer.
    – MrD
    Commented Jul 29, 2015 at 18:26
  • Thank you MrD. I am closer to making this work. But, can you take a look at my edit #4? I am having an issue with assigning a taxonomy term id to a field.
    – Cheryl
    Commented Jul 30, 2015 at 16:27

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.