I haven't been able to track down exactly under which conditions this happens but when you change the language of a node and then save it on a specific site we have, under certain conditions, field_collection thinks it has to update the host entity. It does that however with the loaded entity, which might be the same as we are currently saving. For example because the entity was serialized into $form_state.
What's weird is that the field update hook passes TRUE to deleteRevision(), to avoid updating the host. However, that does not apply if delete() is called for one of the two cases.
Then it takes $this->hostEntity, removes the field item from it and saves it. In hour case, it re-saves the node with the previous language and then everything goes completely crazy. The node ends up with e.g. und in the {node} table, de in {field_data_body} (only a single entry, no value for und) but entity_translation thinks that the entity was changed to de.
When you then edit it you a) have no field values anymore and b) the language selector is disabled. In other cases, not yet sure what's the difference, you still can change the language but trying to save then results in exceptions as the entity already has field values for that language.
The attached patch adds a way to update the host entity within the item so that the correct one is re-saved, but I'm not sure if we shouldn't prevent that deleteHostEntityReference() is called in the first place in this scenario.
| Comment | File | Size | Author |
|---|---|---|---|
| #9 | 2013811.9.field_collection-resave-old-entity.patch | 1.57 KB | jmuzz |
| #1 | 2013811.1.field_collection-resave-old-entity.patch | 1.33 KB | deviantintegral |
Comments
Comment #1
deviantintegral commentedI ran into exactly this same problem. We have some custom code saving a user account, and field collection was undoing any changes to the user table itself (email, password, etc). What was worse was that the returned account from user_save() continued to have the updated data; it was just the database that was wrong.
Here's a snippet of code that triggered this for me; I think the only requirement is to add a field collection to the user entity. We also had the same problems using
entity_form_submit_build_entity();in the same manner as user.module.Comment #2
drummWe've run into this on Drupal.org too.
Comment #3
drummSince this is causing data loss, marking it critical.
Comment #4
jmuzz commentedI tried duplicating this but I may have gotten the context wrong. deviantintegral says "I think the only requirement is to add a field collection to the user entity" but Berdir in the issue summary seems to think it is related to multiple languages.
I added a first_name and last_name field to users as well as a field collection with a text field. I didn't use a form to test it (I wasn't sure where the code posted would go to test it that way) but I threw this into a script:
I tested it with and without the field collection and the name fields as well as the mail was set in both cases.
Can anybody provide more details about how to duplicate this?
Comment #5
drummI confirmed #1 works on dev for Drupal.org, patching 7.x-1.0-beta7. I didn't test 7.x-1.x.
For us, the steps to reproduce are something like:
To debug, I got the backtrace to each call to
user_save()for the last step. I noticed that it was actually called twice, with the second call coming from field collection. Presumably, this is an older copy of the user entity from memory, and it is saving over the first save.If wanted, you can take a look at a Drupal.org dev site, https://www.drupal.org/node/1018084.
Comment #6
jmuzz commentedI followed those steps on a mostly fresh install and wasn't able to duplicate the behavior described. I tried adding and removing some field collection items from the user as well as the patch seems to change what happens when field collection items are removed but the changes to the user were all saved.
I'll try to get access to a Drupal.org dev site.
Comment #7
drummI should say, register as the new user, while logged out. Not sure if it would actually make a difference, but I wouldn't be surprised.
Comment #8
jmuzz commentedThey are blocked by default when I create them that way and I was able to block and unblock them using /admin/people and the user edit form.
Thanks for giving me access to a test site. I'll try it there next.
Comment #9
jmuzz commentedI was able to reproduce it on the test site and the patch fixed it.
A version of this updateHostEntity function was made for #1344672: Field Collection: Field translation (entity_translation) support. to solve a similar problem. I'd like to use the current proposed version of the function from that issue instead of the one supplied by this patch as it has been looked at more, it will make the transition to including entity translation more smooth, and it will be helpful to uncover any more issues it may have.
I tested this on the drupal.org test site and locally and it seems to solve the problem without causing more issues.
Comment #10
drummAgreed, looks good!
Comment #12
jmuzz commentedThanks all.
Comment #14
jiv_e commentedI link the issues having problems related to updateHostEntity function.