Problem/Motivation

Field collection does not support node translation properly. Multilingual sites using the node translation method are not able to use Field collection.

Drupal 7 has two methods for translation: the node translation method used in previous versions of Drupal, and the Field translation method that will be used in future versions of Drupal (see Drupal 7's new multilingual systems (part 4) - Node translation). For the issue covering Field Translation, see #1344672: Field Collection: Field translation (entity_translation) support..

As stated in the module's README.txt

* As of now, the field-collection field does not properly respect different
revisions or languages of the host entity. Thus, for now it is suggested to
only use the field for entities that are not revisionable and translatable.

Proposed resolution

Provide support to have Field collections work with note translation and utilize the $obj->language parameter.

Remaining tasks

* Testing and possible optimization of the update hook in comment #195.
* Both patches comment #194 (which handles the functional changes) and comment #195 (the update hook) need review.

User interface changes

None at present, though some administrative configuration options may be relevant or necessary. For example: whether files used by image fields or file fields should be physically duplicated or whether translated fields should reference the same fid.

API changes

* Use of $langcode and LANGUAGE_NONE would change to be relevant to the host entity.
* Duplication of files for image fields and file fields may occur.

Original (related) reports by dbravender and FiNeX

#1156468: New translations don't inherit parent field collections
#1186878: Node reference inside field_collection doesn't work with i18n

BEWARE: The patch on #211 includes an implementation of field_collection_update_7005(). When updating the field_collection module after using this patch, keep an eye on your field_collection_update hooks, as if another patch gets in which implements 7005 then that will not be executed on your site - you will need to do so manually.

Files: 
CommentFileSizeAuthor
#217 interdiff-211-217.txt3.27 KBjrglasgow
#217 1316162-fix-shared-field_collection_items-217.patch3.27 KBjrglasgow
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 1316162-fix-shared-field_collection_items-217.patch. Unable to apply patch. See the log in the details link for more information.
[ View ]
#211 field_collections-1316162-211.patch11.54 KBjrglasgow
PASSED: [[SimpleTest]]: [MySQL] 162 pass(es).
[ View ]
#106 field_attach_prepare_translation_alter.txt3 KBbderubinat
#98 Screen Shot 2013-03-30 at 8.24.08 AM.png48.95 KBRobKoberg
#98 Screen Shot 2013-03-30 at 8.48.19 AM.png23.78 KBRobKoberg
#98 Screen Shot 2013-03-30 at 8.54.18 AM.png30.36 KBRobKoberg

Comments

Here is a quick fix for Clone field collections as new, separate entities when creating a new translation.
Create a new module with this :

<?php
function mymodule_entity_load($entities, $type){
    if(
arg(0) == 'node' && arg(1) == 'add' && !empty($_GET['translation'])){
        foreach(
$entities as $id => &$entity){
            if(
is_a($entity,'FieldCollectionItemEntity')){
                unset(
$entity->item_id);
            }
        }
    }
}
?>

Status:Active» Needs review
StatusFileSize
new1.49 KB
PASSED: [[SimpleTest]]: [MySQL] 80 pass(es).
[ View ]

Here is a quick patch to separate entities when creating or updating a translation.

StatusFileSize
new1.76 KB
PASSED: [[SimpleTest]]: [MySQL] 80 pass(es).
[ View ]

Adding a check only for node entity types

Super! Works great so far! Thanks!

Patch works only if view mode is embedded

someone has a solution?

Sorry JulianH I'll take a look asap and I'll test with embeddeds views. By the way I think the last patch it's a quick win but there are much work to do with i18n fields.

Works for me. I am implementing two sites using this patch. Is this a clean solution and can I go ahead and create content using this?

Just confirming this works on a site I'm working on. Even if it's not perfect it seems like it helps.

Works for me too. Thanks!

if the field collection has a field collection in it the parent collection gets a new copy but the child one doesnt
if think its cause the if ($entity_type == 'node') fails for the child collection

Thanks! It works perfect!

In my case if I have a translated node with field collections, when updating one of the translations the changes applied also to the all other nodes in the translation set.

Applying the patch from #4 solved this.

Is this going to be commited?

Priority:Normal» Major
StatusFileSize
new1.5 KB
PASSED: [[SimpleTest]]: [MySQL] 78 pass(es).
[ View ]

+1 for patch #4. Here's an update to address #12 (field collections within field collections), though not sure if these is a better way to implement this.

Upping priority since this bug can cause data loss (through content overwriting).

Sounds good. Maybe we can even solve this generally though?

If a new host-entity is saved which already contains field-collections, those collections must be new too. Else, we've to clone them. This should generally solve problems with cloning entities, regardless whether its content translation, node clone or custom code. thoughts?

I tesed the function with Field collection 7.x-1.0-beta3 and it worked! thanks!

Still works... I've been using it the past few months. Can we get this commited?

I'm looking for entity_translation support. This patch won't interfere with entity_translation, will it?

See #1344672: Field Collection: Field translation (entity_translation) support.

Unfortunately, the patch doesn't work at all when Widget is "Hidden".

This patch is actually a copy of but adapted for version field_collection beta 4:

<?php
Index
: field_collection.module
===================================================================
---
field_collection.module    (revision 65)
+++
field_collection.module    (working copy)
@@ -
609,6 +609,26 @@
       if (!empty(
$item['entity']->is_new)) {
        
$item['entity']->setHostEntity($entity_type, $entity, LANGUAGE_NONE, FALSE);
       }
+      else {
+        if (
$entity_type == 'node' || $entity_type == 'field_collection_item') {
+         
// reset item_id when it's a new translation
+          if (isset($entity->nid) && !$entity->nid) {
+           
$item['entity']->item_id = '';
+          }
+          else {
+           
$query = new EntityFieldQuery();
+           
$query->fieldCondition($item['entity']->field_name, 'value', $item['entity']->item_id, '=');
+            if (isset(
$entity->nid)) {
+             
$query->entityCondition('entity_id', $entity->nid, '!=');
+            }
+           
$result = $query->execute();
+           
// reset item_id if exists other node with the same instance
+            if (!empty($result)) {
+             
$item['entity']->item_id = '';
+            }
+          }
+        }
+      }
      
$item['entity']->save(TRUE);
      
$item = array('value' => $item['entity']->item_id);
     }
?>

Still not working when Widget is "Hidden".

StatusFileSize
new1.28 KB
PASSED: [[SimpleTest]]: [MySQL] 78 pass(es).
[ View ]

@jdanthinne, could you be more specific when you say "when Widget is 'Hidden' "? Do you mean the display widget for the collection, or the display widget on fields within the collection? I can't imagine how a display widget would interfere.

Here's the same as #21 with some comment cleanup as a real patch.

I did some testing and this seems to work well for me.

I mean that in the content type that contains a Field Collection, the field widget type is "Hidden".

Status:Needs review» Needs work

Ah, now I'm able to reproduce.

This is because when Field Collections are set to "hidden" (rather than embedded), they're edited in a context completely separate from the host entity.

One option is to add code to check for this case in the hook_field_presave, but it might make more sense to get rid of the case entirely (e.g., when you translate content, it shouldn't automatically get the source node's collections).

Status:Needs work» Needs review
StatusFileSize
new1.89 KB
PASSED: [[SimpleTest]]: [MySQL] 78 pass(es).
[ View ]

Here's #23 with additional code that checks for the hidden widget case.

#26 working better now with hidden widget: before this patch, the old collections (in the original language), were still linked to the translated node, so when I change one instance, it changed in both languages (unwanted!).
Now, the old collections are unlinked from the translated node (fine!), but they're not duplicated, assigned to a new language and linked to the new node… that would be nice(r) because as now, you have to recreate the collection in the translated node (instead of translating them).
Despite that workflow detail, #26 is already great!

I had an issue with field-collection translations where one translation sort of over-wrote the other translations. At least this is how it looked.

Anyway, patch #26 fixed the problem for me. Thumbs up!

Priority:Major» Normal
Status:Needs review» Needs work

I'm against adding node specific code like that. Can't this be abstracted more?

@tim.plunkett Do you know of other ready-made entity types that make use of the content translation (vs. entity field translation) paradigm that could be used to make/test a more abstracted patch?

I am having an issue with #26, but not with #15.

The issue may have to do with this patch for field_collection, http://drupal.org/node/1239946#comment-5410010. This patch ensures that "empty" or "duplicate" field collection items are not saved every time you save / edit a node with a field collection. That patch has worked well.

I am also using Workbench with Workbench Moderation.

My field collections are using the embedded widget.

With #15, everything works as expected!

With #26, if I made a new translation of a node (content type page) with a field collection and save as "published" the first time, the reveals are all gone on the translated page. They remain on the original page. If I instead save the content as "draft" the first time, the field collections are kept. If I then change the state from "draft" to "published", the field collections are kept. The only time the field collections are removed is when I first save the translation as "published".

This isn't a huge issue, but one to consider.

I may have time to look into it a bit more. My guess though is that it has something to do with the two field collection patches and Workbench Moderation.

same as pandaeskimo. #15 works fine with the patch he mentions. thanks a lot!

Status:Needs work» Needs review

#26 works for me. I didn't have problem when i save the first time like explain in #31.

In Europe translation is not a feature request... it's a critical bug ;)

#26 works here as well, thanks

Issue tags:+i18n compatibility

Tagging

Suscribe

Any updates on this one?
Using patch #26 fixed the problem, how will this evolve?

Status:Needs review» Reviewed & tested by the community

For #26.

Status:Reviewed & tested by the community» Needs work

Patch #26 corrects the user-facing behavior, but "language" is still stored as 'und' for all translations in both the field collection and the fields within the field collection.

Status:Needs work» Reviewed & tested by the community

Believe that's expected behavior. This is about the "content translation" paradigm, the fields you're referring to are related to the "field translation" paradigm; believe there's a separate ticket for this.

Can you point me to that ticket?
I thought "field translation" referred to things like labels and help text.

Status:Reviewed & tested by the community» Needs work

I and tim.plunkett have both stated that we'd prefer a more general solution, see #16 and #29. Let's do so:

If a new host-entity is saved which already contains field-collections, those collections must be new too. Else, we've to clone them. This should generally solve problems with cloning entities, regardless whether its content translation, node clone or custom code.

#26 saved my life, for now. I applied it to 7.x-1.x-dev 2012-Jul-28 and it seems to work as expected (i.e. translates the fields' content).

Priority:Normal» Major

According to the Priority handbook page "Issues which have significant repercussions but do not render the whole system unusable are marked major."

Version:7.x-1.x-dev» 7.x-1.0-beta4

#26 works for me,
I didn't have the problem as outlined i #31 so I guess as @pandaeskimo say it is a Workbench Moderation problem

I am using beta 4

Version:7.x-1.0-beta4» 7.x-1.x-dev

I have recently updated to the latest dev release from Sept. 12 for another issue and have found that when I create a new translation the field collection does not get cloned as a new entity, meaning that when I change one node the other one changes as well - which is bad for multilingual. It seems this patch did not make it into the latest dev and the new dev release _field_presave function is quite different since the introduction of revisioning.

StatusFileSize
new2.43 KB
FAILED: [[SimpleTest]]: [MySQL] 1 pass(es), 2 fail(s), and 0 exception(s).
[ View ]

Here is a patch for the latest dev, please give it a try as I have only done limited testing.

StatusFileSize
new2.38 KB
FAILED: [[SimpleTest]]: [MySQL] 77 pass(es), 5 fail(s), and 11 exception(s).
[ View ]

Doh! Same patch as #51 without the dpm() in it.

Status:Needs work» Needs review

just triggering testbot

This patch brokes the node revision revert feature:

EntityFieldQueryException: Motore di archiviazione files non trovato in EntityFieldQuery->queryCallback() (line 1180 of /Users/paolo/Zend/workspaces/DefaultWorkspace/twinbit/hart/tim/includes/entity.inc).

StatusFileSize
new2.41 KB
FAILED: [[SimpleTest]]: [MySQL] 127 pass(es), 5 fail(s), and 2 exception(s).
[ View ]

Please, find attached a patch to make this patch works also on node revisions reverting.

StatusFileSize
new627 bytes
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch entity-check-false.patch. Unable to apply patch. See the log in the details link for more information.
[ View ]

A big THANK YOU! to everybody who contributed to this issue. I already feared that this will break my website's neck when I discovered that field_collection doesn't support full content translation. But then I found this issue. :-)

I only noticed one side effect: in field_collection.module on line 1611 the result of field_collection_item_load isn't tested before it's used as object. When no item could be loaded (e.g. it doesn't exist yet, what is the case for every newly created node translation) PHP raises a notice. By ensuring $entity isn't FALSE we could prevent this. Attached is a tiny patch for this particular detail.

Their is a problem with the test bot?

It should be noted that the patch needs the latest dev of Entity API installed, otherwise it will break the site.

When trying to save a node with a field collection:

Fatal error: Call to undefined method FieldCollectionItemEntity::isDefaultRevision() in [...]/sites/all/modules/field_collection/field_collection.module on line 538

Installing latest dev of Entity API fixed it.

#55 works perfectly for me using Embedded widget.

#55 and #56 working for me as well. Though I don't think this can RTBC without a test pass? Does this need a new test or is testbot just stuck on those patches for some reason?

Status:Needs review» Needs work

It's been repeated several times in this thread that any patch with node-specific code will not be accepted (#16, #29, #45); needs to be a more generic solution.

Going to mark this as needs work, as such.

StatusFileSize
new2.95 KB
FAILED: [[SimpleTest]]: [MySQL] 127 pass(es), 5 fail(s), and 0 exception(s).
[ View ]

I combined #55 and #56 together in this patch which worked for me.

I've tried the patch in #55, but when changing language of a node the reference to the field collections (from the node) seems to break. I.e the row in the field collection field (on the node) disappears after saving the node. The field collection is still in the database, just not referenced any more.

You should remove the whitespace.

+++ b/field_collection.moduleundefined
@@ -883,17 +883,35 @@ function field_collection_field_settings_form($field, $instance) {
+      if ($entity = field_collection_field_get_entity($item)) { ¶

Status:Needs work» Needs review
StatusFileSize
new2.88 KB
FAILED: [[SimpleTest]]: [MySQL] 127 pass(es), 5 fail(s), and 0 exception(s).
[ View ]

Rerolled

What's up with the bot? It's postponed after 2+ days.

StatusFileSize
new2.88 KB
FAILED: [[SimpleTest]]: [MySQL] 127 pass(es), 5 fail(s), and 0 exception(s).
[ View ]

Attaching again?

Status:Needs review» Needs work
Issue tags:-i18n compatibility

The last submitted patch, field_collection-1316162-65.patch, failed testing.

Status:Needs work» Needs review
Issue tags:+i18n compatibility

Status:Needs review» Needs work

Do we need to adapt the tests?

Version:7.x-1.x-dev» 7.x-1.0-beta4

Super!

#26 worked for me.

Finally content in field collections don't get overwritten between different languages.

Thx!

Version:7.x-1.0-beta4» 7.x-1.x-dev

Status:Needs work» Needs review
Issue tags:-i18n compatibility

Status:Needs work» Needs review
Issue tags:-i18n compatibility

#65: field_collection-1316162-65.patch queued for re-testing.

Status:Needs review» Needs work
Issue tags:+i18n compatibility

The last submitted patch, field_collection-1316162-65.patch, failed testing.

Issue tags:+i18n compatibility

#65 worked perfect for me. Applied clean & fixed the problem even with collections that were previously translated with the patch in #26.

Retriggering bot.

#65: field_collection-1316162-65.patch queued for re-testing.

StatusFileSize
new2.92 KB
FAILED: [[SimpleTest]]: [MySQL] 127 pass(es), 5 fail(s), and 0 exception(s).
[ View ]

I was having a problem with this patch when making a revision. When the new revision is created the field_collection gets reset to empty.

This patch solves this problem for me. It probably won't pass the unit tests, I haven't had a chance to take a look at that yet.

Status:Needs review» Needs work

The last submitted patch, field_collection-1316162-79.patch, failed testing.

Patch #65 worked for me. #26 failed.

In Europe translation is not a feature request... it's a critical bug ;)

Absolutely agree.

Confirm that #65 works

Tried the patch in #65.

It seems to work, ie the field collections on my node are translatable, however it seems to have introduced a bug with the node title. If you update the title on the node, it does not get updated (regardless of language) :-/

Reverting the patch this problem goes away

Update: the problem seems to be on line 36 of the patch, ie:

+              // Reset item_id if another node with the same instance exists.
+              if (!empty($result)) {
+                $item['entity']->item_id = '';
+              }

If i comment out the line $item['entity']->item_id = ''; this fixes the node title problem, but will most likely break something else with the patch.... Unfortunately I dont understand the module/patch in great enough detail to fix both issues

c4rl - can you help?

I tried the patch in #79.
- After translating a node, it first looks ok. But If I edit the translation then the collection get emptied. Editing it again and putting some content in the collection "fixes" the problem since the content is saved. However, editing it again, the collection is empty again... (same if I edit the original node, the collection is empty)
- The node title is correctly translated

edit: If i comment the same line as #84 then the problem is fixed. It looks like this portion has been added to handle revisions if I'm right.
edit3: Commenting the lines worked because before that I didn't comment them out and translated. Then the "empty collection" issue appearead so I commented these lines and if fixed this issue. But with these lines commented, if I create a new node and try to translate it it doesn't work (the text stay the same between the languages, if the French translation is edited, the english version get the same text).

edit2: Commenting these lines make the test pass locally. Without the comment I have the same 5 errors as reported by the testbot.

Status:Needs work» Needs review
StatusFileSize
new2.94 KB
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch field_collection-1316162-86.patch. Unable to apply patch. See the log in the details link for more information.
[ View ]

So I did some more test and tried some things with the code.

<?php
// Reset item_id when it's a new translation.
if (isset($entity->nid) && !$entity->nid) {
 
$item['entity']->item_id = '';
}
else {
  ...
?>

I never saw a "nid" property on the entity. On my tests there are "item_id" and "revision_id" among other properties but I never saw a "nid". Another thing, is that they are always defined, even for a new translation. On the other hand, the "$host_entity" has a "nid" field, and it's NULL on new translation.

Given that the $entity doesn't have a nid, the following line should be changed too. It should be either $entity->item_id or $host_entity->nid. In the following patch I used $host_entity->nid but I'm not sure about that.

<?php
if (isset($entity->nid)) {
 
$query->entityCondition('entity_id', $entity->nid, '!=');
}
?>

With these changes it works well on my little test without revisions. I did not test this with revision.

edit: I quickly tested with revision and it looks like it's working. However I never really used revisions so I may be missing something here.

Hi, patch #86 works fine on my latest test site. I'm not using node revision too.

Hi, can confirm that #86 solved the translation issue for me.
Just to be sure, I've removed the previously initialized translations (let the newly updated module make a new #items id copy).

Thank you!

Status:Needs review» Reviewed & tested by the community

#86 works great! Thank you! Because two other confirmed that #86 works I set the status to RTBC :)

#86 works here aswell!

Status:Reviewed & tested by the community» Needs work

most of a coding standards review

+++ b/field_collection.moduleundefined
@@ -886,17 +886,35 @@ function field_collection_field_settings_form($field, $instance) {
+              $query->fieldCondition($item['entity']->field_name, 'value', $item['entity']->item_id, '=');

no need for = here, i think its the default, but this is just minor

+++ b/field_collection.moduleundefined
@@ -886,17 +886,35 @@ function field_collection_field_settings_form($field, $instance) {
+                $query->entityCondition('entity_id', $host_entity->nid, '!=');

i suppose we should use <> here instead of != since it is compatible with all databases

+++ b/field_collection.moduleundefined
@@ -1586,7 +1611,7 @@ function field_collection_field_get_entity(&$item, $field_name = NULL) {
+    if (FALSE !== $entity AND $entity->revision_id != $item['revision_id']) {

AND should be &&
and FALSE should be in the second part of comparison:
$entity !== FALSE

Status:Needs work» Needs review
StatusFileSize
new2.93 KB
PASSED: [[SimpleTest]]: [MySQL] 132 pass(es).
[ View ]

Thanks for the review : )

fieldCondition and addFieldCondition don't have a default value for the $operator so it may be safer to keep it.

For the "<>", the addFieldCondition function take care of replacing the operator. I think that the '!=' is more readable and common so I left it.

So in the following patch I only fixed the error described in the last remark about the !== comparaison.

Status:Needs review» Reviewed & tested by the community

ah..nice

if ($operator == '!=') {
  $operator = '<>';
}

was not aware of that:)

Setting back to rtbc, even though i am not sure maintainer's concerns @#45 are resolved

This is not working for me. I tried the last and the #86 patch. I also tried Entity Translation but it didn't work either.
I have a field collection with multiple values which should be translated in three languages but its impossible
If I try to translate the fields they just take the new value and substitute the old one, thus erasing it.

See the issue title "Support content translation". Content translation is the thing when creating new nodes for every language and as you can see the patch there is special handling for nodes.

Patch #86 works perfect.

Thank you very much!

Patch #92 worked for me too.

Thank you!!

Status:Reviewed & tested by the community» Needs work
StatusFileSize
new30.36 KB
new23.78 KB
new48.95 KB

The patch #92 did not work for me after updating to 7.x-1.x-dev. field_collection fields are always saved as LANGUAGE_NONE. They are associated correctly with their node parent. Not sure why, but this makes the latest version (the translated version) of the field's value show for the original language as well as the translated version. In the attached screen grab of a table that stores the field value of a field in a field collection, you can see that after switching to to the translate/add or edit creates the translate set with LANGUAGE_NONE.

I am not using entity_translation -- just the core modules and i18n (is there something else required?).

A little background: There are three field_collection_items for the node, so you are seeing the results for one node and its translated node. The first three are for are for english and second three are for the spanish version. I have only set the value for the first one in the second set (been working on this for a while -- restore from backup, try something, get same result, restore from backup, lather, rinse, repeat...)

I have also attached the field_collection_item table along with the field_collection's field table. These show that the IDs are of the items are mapped correctly to their respective nodes, but the latest version shows for both the translated and original node.

Any ideas?

#98: I've tried to reproduce this with a basic test setup with content translation:

  • Vanilla Drupal installation with Field Collection 7.x-1.x-dev, I18N (Multilangual content + i18n) enabled.
  • Added a FC field "Collection" to the Basic Page bundle. Configured the FC entity to have 1 extra field called "Body" (Textarea)
  • Basic page is set to "Multilangual support with translation" enabled, no revisioning
  • Two languages added to the site: English & Dutch

I created a new basic page node in English and translated it to Dutch (2 nodes => 1 tnid) The database reflects those changes: the field collection entity itself will be LANGUAGE_UND but field_data_field_collection which contains the actual relation between the node entity and the FC entity makes the correct mapping: the EN & NL nodes each will each be related to separate FC entities. To me, there doesn't seem any need to assign languages to the FC entities themselves as those are defined through the host entity to which they are assigned.

In your screenshots, I see the same configuration, but the FC entities assigned to the ES node do have the same, duplicated, content as the onces assigned to the EN node. Try changing the content of the FC field on the ES node and you should see how those get reflected correctly. I didn't see any NL content appear on my EN nodes when trying to reproduce this.

I do believe we need to make sure that this patch needs to meet these conditions:

1. Work with Content translation, Entity translation & Field translation.
2. Be entity type agnostic (as pointed out by Fago et al.)

I don't think we've established those goals are met, yet.

"Try changing the content of the FC field on the ES node and you should see how those get reflected correctly."

That is what I did. For the english node, I had a value of "Login or Sign up". For the spanish version I had "Ingresa o regístrate". ( http://drupal.org/files/Screen%20Shot%202013-03-30%20at%208.24.08%20AM.png )

Using the language switcher and viewing in either English or Spanish showed "Ingresa o regístrate". One thing that might be an issue is that I am not using URL for language detection (/admin/config/regional/language/configure). I am using Session, User, Browser, and Default -- in that order. I have the same URLs for the en and es nodes.

That said, I switched back to using node fields rather than FC entities.

I was also having problems with entityreferences, which also might be related to not using URL for detection. I worked around that with:

if ($language->language == 'en') {
  $auth_wrap = entity_metadata_wrapper('node', $author);
} else {
  $translations = translation_node_get_translations($author->tnid);
  $es = $translations['es'];
  $auth_wrap = entity_metadata_wrapper('node', $es->nid);
}

This is not possible with field_collection because of having LANGUAGE_NONE.

Status:Needs work» Needs review
StatusFileSize
new3.1 KB
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch field_collection-1316162-101.patch. Unable to apply patch. See the log in the details link for more information.
[ View ]

Would be great to get a summary of testing steps. I ran into this issue on a Content Translation-using site and applied the patch. My use case is simply to translate a new node and check in the database that the FCs are not using the same IDs.

Before #92: the `value`s would be the same.

After #92: Still seeing the translations having the same `value`s.

I tweaked the condition that resets the `item_id` on the entity. It's clear that it should work for nodes without `nid`s. However, it was checking that `$host_entity->nid` was always set, and this was not the case when using content translation (`isset()` returns `FALSE` on `NULL`s by design).

After doing that, new field collection items were created for the translated node, as should happen. The content of the newly-created field collection items is the same as in the original node (I didn't change anything), also as expected.

I instead check that `$host_entity_type == 'node'` now. I don't see any problems with this change, but I am not fully educated on the issue, so let me know if there are any.

Re. netsensei #99: This issue is to support content translation only. I think that #2 is currently a non-issue. Entity translation is being handled in a separate issue.

I think this patch should be reviewed and concrete steps given if it still needs work. We need something working in Field Collection sooner than later, even if it's just in dev.

Status:Needs review» Needs work

The last submitted patch, field_collection-1316162-101.patch, failed testing.

#101 worked for my case.

I use content translation for my content in Drupal. I have one content type and have two field collections inside. I applyed patch #101 and now I can translate it. It work for node template. I did not checked on view and panel.

Thank wizonesolutions

I have test the patch of #65, #92, #101

all failed. I think I am missing something. However below is my steps:

1: create a field collection field for content type : article.
2: add a textfield for field collection.
3: i18n enabled, and the article enable for translation too.
4: create an article in English, with field collection field "test string"
5: go to translation tab, and add translation for this article.
I pay attention for field collection field specially and confirm it has been translated.
suppose the translation string is "测试数据"
6: then I visit the both english and chinese.
both language, the field collection field, the value becomes “测试数据”

Am I do something wrong? thanks for help.

BTW, I update my entity to dev. see below:
http://drupal.org/node/1782664

ah.. ignore my post above.
I apply the patch in wrong place.

After I found this problem and apply the patch of #101, the field collection field can be translated now.

Thanks for great work of guys.

Hope this patch can be embeded into field_collection core in soon:)

Very good field_attach_prepare_translation alter function to copy content of node's field_colection when translating. Merci Etienne.

http://www.lapetitepausetechnique.net/2012/09/field_collection-et-i18n/

It works for me with two fixes

***************
*** 1,6 ****
  function <modulename>_field_attach_prepare_translation_alter(&$entity, $context) {
    // Champs à synchroniser
!   $sync_fields = i18n_sync_node_fields($entity->type);
    // Champs appartenant au bundle
    $entityFields = field_info_instances('node', $entity->type);
--- 1,10 ----
  function <modulename>_field_attach_prepare_translation_alter(&$entity, $context) {
    // Champs à synchroniser
!   if (module_exists('i18n_sync')) {
!     $sync_fields = i18n_sync_node_fields($entity->type);
!   } else {
!     $sync_fields = array();
!   }
    // Champs appartenant au bundle
    $entityFields = field_info_instances('node', $entity->type);
***************
*** 61,66 ****
--- 65,71 ----
            // on attache la FC à l'entité cible, grâce à l'id de l'item nouvellement créé
            $entity->{$entityField}[LANGUAGE_NONE][$i]['value'] = $field_collection->item_id;
+   $entity->{$entityField}[LANGUAGE_NONE][$i]['revision_id'] = $field_collection->item_id;
            $i++;
          }

Status:Needs work» Needs review
Issue tags:-i18n compatibility

#101: field_collection-1316162-101.patch queued for re-testing.

Status:Needs review» Needs work
Issue tags:+i18n compatibility

The last submitted patch, field_collection-1316162-101.patch, failed testing.

For anyone still getting burned by this bug (or for that matter getting burned by using Node Clone on nodes with field collections), first apply my previous patch (or bderubinat's, but I haven't tested that one). That will stop further damage.

To repair your previous entries and ensure that, for example, removing a field collection entry doesn't remove it from other nodes from which you didn't want it removed, you can implement this script I've detailed in a gist: https://gist.github.com/wizonesolutions/5567549

It will give new item_ids to field collection items that it detects as appearing more than once. All my testing has indicated this is safe, but if not, please leave a comment on the gist. I hope this helps someone.

Thanks to Project Ricochet for sponsoring my time on this.

Status:Needs work» Needs review
StatusFileSize
new2.94 KB
PASSED: [[SimpleTest]]: [MySQL] 132 pass(es).
[ View ]

#101 worked for me, but after changed the file paths to the relative ones to the module folder. Here is my version that applyes cleanly from inside the field_collection module directory, aganst last dev

desarrollo2.0: Thanks for the reroll. My version has been working well for quite some time, and we realized it also fixes the same problem occurring when cloning nodes. I think we need another reviewer before this could be RTBC'd, but it's looking pretty good to me. Would love this to make it into the module.

Thanks wizeonesolutions and desarrollo2.0, it works for me!

However, I'm curious why checking if $host_entity_type == 'node'. If it's because the entity's id is unkown, you/we could use entity_extract_ids.

StatusFileSize
new2.9 KB
PASSED: [[SimpleTest]]: [MySQL] 132 pass(es).
[ View ]

#110 worked for me, although I had to recreate the patch for Field Collections 7.x-1.0-beta5.

Here you go:

#101: field_collection-1316162-101.patch queued for re-testing.

#113 worked for me, thanks.

Status:Needs review» Reviewed & tested by the community

Patch #113 just saved my ass.
Works like a charm.

- ignore this -

This still doesn't work if "Create new revision" is checked when the new node is created. Test case:

  1. node A in language A with a field_collection_item (item_id=1, revision_id=1)
  2. access the translate tab of the node and try to create a new node B with language B
  3. check "create new revision" in the publishing options

The result is: Instead of a copy of the field_collection a new revision (item_id=1, revision_id=2) is created that is linked to node B. The data for the older revision is lost. Editing those nodes later on leads to more odd behavior like data not being saved …

This also happens if the revisioning module is enabled. Since it forces new revisions when editing a node.

Status:Reviewed & tested by the community» Needs work

Patch #101 worked fine for me, but I was working in an environment where I wasn't able to use patched modules.

I therefore created my own module and implemented the following hook:

function field_collection_translation_field_attach_presave($entity_type, $entity) {
  // Clear the item_id on the field collection entity before saving in order to force creation of a new field
  // collection rather than overwriting the original
  if (empty($entity->is_new)) {
    if ($entity_type == ‘field_collection_item’) {
      if (isset($entity->item_id)) {
        $entity->item_id = ”;
        $entity->save(TRUE);
      }
    }
  }
}

(see http://theduttons.org/?p=7)

This worked perfectly, and field collection translation worked correctly once the new module was enabled.

.. hope that helps someone out !

Patch #113 (rewrap of #101) applies fine over 7.x-1.0-beta5+1-dev, and works for me.
I do not use node revisions, so I cannot say anything about #119.

For those looking for field translation (entity translation module support),
remember that other issue is the appropriate: #1344672: Field Collection: Field translation (entity_translation) support.

#113 works for me with i18n and revisions (workbench). I could not replicate the problem described in #119.

Is it possible that the problem described in #119 was caused by testing the #113 patch on field_collection items that were created before the patch was applied?

Some weird things happened to field_collections that were made prior to installing the #113 patch on my local development environment.

I can still confirm the issue mentioned in #119 using beta5+#113. Although it's not apparent from the UI the state in the database is still inconsistent.

Prerequisites

  • minimal profile
  • modules: field_collection, blog, i18n_node enabled.
  • two languages enabled (en and de)
  • add a field_collection to the blog content-type (field_test) and a text-field to the field_collection (field_textfield)

Steps to reproduce

  1. Add a new blogpost in one language (ie. en)
  2. Translate the blogpost via Translate - Add Translation into the other language (ie. de) and check the "Create new revision" checkbox
  3. Hit save

Expected result

Two independent entities of type field_collection are created.

Actual result

The value of the field_collection in the translated node is stored in a new revision of the same field_collectiont entity (entity_id=1).

Actual result in the database

> select * from field_data_field_test;
+-------------+--------+---------+-----------+-------------+----------+-------+------------------+------------------------+
| entity_type | bundle | deleted | entity_id | revision_id | language | delta | field_test_value | field_test_revision_id |
+-------------+--------+---------+-----------+-------------+----------+-------+------------------+------------------------+
| node        | blog   |       0 |         1 |           1 | und      |     0 |                1 |                      1 |
| node        | blog   |       0 |         2 |           2 | und      |     0 |                1 |                      2 |
+-------------+--------+---------+-----------+-------------+----------+-------+------------------+------------------------+
> select * from field_revision_field_textfield;
+-----------------------+------------+---------+-----------+-------------+----------+-------+-----------------------+------------------------+
| entity_type           | bundle     | deleted | entity_id | revision_id | language | delta | field_textfield_value | field_textfield_format |
+-----------------------+------------+---------+-----------+-------------+----------+-------+-----------------------+------------------------+
| field_collection_item | field_test |       0 |         1 |           1 | und      |     0 | Testcontent           | NULL                   |
| field_collection_item | field_test |       0 |         1 |           2 | und      |     0 | German test content   | NULL                   |
+-----------------------+------------+---------+-----------+-------------+----------+-------+-----------------------+------------------------+

Expected result in the database

> select * from field_data_field_test;
+-------------+--------+---------+-----------+-------------+----------+-------+------------------+------------------------+
| entity_type | bundle | deleted | entity_id | revision_id | language | delta | field_test_value | field_test_revision_id |
+-------------+--------+---------+-----------+-------------+----------+-------+------------------+------------------------+
| node        | blog   |       0 |         1 |           1 | und      |     0 |                1 |                      1 |
| node        | blog   |       0 |         2 |           2 | und      |     0 |                2 |                      2 |
+-------------+--------+---------+-----------+-------------+----------+-------+------------------+------------------------+
> select * from field_revision_field_textfield;
+-----------------------+------------+---------+-----------+-------------+----------+-------+-----------------------+------------------------+
| entity_type           | bundle     | deleted | entity_id | revision_id | language | delta | field_textfield_value | field_textfield_format |
+-----------------------+------------+---------+-----------+-------------+----------+-------+-----------------------+------------------------+
| field_collection_item | field_test |       0 |         1 |           1 | und      |     0 | Testcontent           | NULL                   |
| field_collection_item | field_test |       0 |         2 |           2 | und      |     0 | German test content   | NULL                   |
+-----------------------+------------+---------+-----------+-------------+----------+-------+-----------------------+------------------------+

After that field_collection behaves weird:

After editing the translated node again - this time without checking the "Create new revision" checkbox - the just edited value is lost and the node is displayed as if the field_collection is empty.

Indeed the field_data_field_test table now has two entries with two entities - but the newly created one has no value in field_data_field_textfield.

Status:Needs work» Needs review
StatusFileSize
new1.25 KB
FAILED: [[SimpleTest]]: [MySQL] 132 pass(es), 0 fail(s), and 31 exception(s).
[ View ]

This patch fixes it for me regardless of the revision setting. It simply forces the creation of a new field_collection entity when the host_entity is new.

At this point field_collection is unable to handle multiple host-entities pointing to the same field_collection-entity anyway.

This patch comes without any special-cases for the node module.

Status:Needs review» Needs work

The last submitted patch, field_collection-new_entity_for_new_host_entity.patch, failed testing.

StatusFileSize
new1.13 KB
PASSED: [[SimpleTest]]: [MySQL] 132 pass(es).
[ View ]

Fixed notices and whitespace.

Status:Needs work» Needs review

Version:7.x-1.x-dev» 7.x-1.0-beta5
StatusFileSize
new3.18 KB
PASSED: [[SimpleTest]]: [MySQL] 132 pass(es).
[ View ]

adding consolidated patch for beta5 release

@prdctvtxt: There is no need to consolidate the patch. Mine works instead of #110 or #113 for both 1.x-dev and 1.0-beta5 :)

This works for me as well. RTBC?

Status:Needs review» Needs work

+++ b/field_collection.module
@@ -903,9 +904,35 @@ function field_collection_field_presave($host_entity_type, $host_entity, $field,
+        ¶

Whitespaces!

Yeah right. We finally have a working RTBC patch after 133 comments. And what is the reaction? Setting it back to Needs Work because there is one an empty line is aligned with the rest of the block (which can be changed easily before commiting). That's the way to lose contributors ;)

@yanickoo: the patch that is RTBC is not even the patch that has the whitespace. #128 should be committed instead of #130

Status:Needs work» Needs review
StatusFileSize
new3.17 KB
PASSED: [[SimpleTest]]: [MySQL] 132 pass(es).
[ View ]

The patch in #128 does not look complete. Compare it with the patch from #130.

Removed the whitespaces :)

Version:7.x-1.0-beta5» 7.x-1.x-dev
Status:Needs review» Needs work

@yanickoo: it is complete. it just handles a more general case and therefore is much simpler. Test it!

It's not code-size that counts, it's functionality ;)

Status:Needs review» Needs work

Comparing #128 with #130:

  • #128 works against the entity-interface. It simply says: If the host-entity is new, then we need to create new field_collection-entities. Content translation is just a special case of that (a node is copied over with all it's content, the language field reset, and is_new is set to TRUE).
  • #130 tries to special-case it's way out of the issue. Instead of looking at $entity->is_new it checks for the entity_type, for the presence of i18n_node and $entity->translation_source. It then forces new field_collection-entities. It essentially works the same way as #128 but does it only for the special case of i18n_node.

My tests showed that the underlying problem is that field_collection is unable to handle a field_collection-entity that's shared between multiple host-entities. #128 avoids this situation in general while #130 and the patches before avoid it only for one special case.

Also there was an error in the logic of the original code: If $host_entity->revision was set a new field_collection-entity revision was created even if $host_entity->is_new was set to true (=the new revision is the first).

Essentially with the code from #128 in place the rest of #130 or #136 is dead code: Special cases where the general case already handles everything.

StatusFileSize
new1.11 KB
FAILED: [[SimpleTest]]: [MySQL] 133 pass(es), 2 fail(s), and 0 exception(s).
[ View ]

Here is a test that tries to create copies of a node with field_collections. It fails without #128.

Status:Needs work» Needs review
StatusFileSize
new2.22 KB
PASSED: [[SimpleTest]]: [MySQL] 135 pass(es).
[ View ]

This patch includes #128 and the tests from #140

Tests should pass.

Status:Needs work» Needs review

I'm pretty sure #141 would also make #1416416: Add support for node_clone work.

Hi ; is there a #136 vs #141 doc. ?

@gregory_kapustin take a look at #139: #136 is essentially #128+#113 which has been put in in #130 and re-rolled without whitespace errors in #136. Both @prdctvtxt and @yannickoo didn't notice respectively believe me that #128 was indeed meant instead of #113 not additionally to it. This caused additional confusion …

Essentially there are two ways to tackle this issue in this bug-report:

  • #113 (and patches before that): „if we are translating a node (=copying a node object and saving it as a new node) then force a new field_collection_item.“
  • #128: „force a field_collection_item whenever we're saving a new entity.“
  • #130 and #136 combine those two. But since #113 is only a special case of #128 this doesn't make a lot of sense: „if we are creating a new entity then also create a new field_collection_item - oh and if the new entity is a new node created via node-translation and the 'create new revision checkbox is not checked' then … do the same anyway.“
  • #141 is #128 packed with a unit-test.

Can we finally get over this confusion and have people test things before they make any presumptions about what "looks complete" or not? I feel like I keep repeating myself over and over and nobody cares to read / test.

Status:Needs review» Reviewed & tested by the community

so. patch in #141 takes care of #45 and has a test.
it is rtbc. all other patches/approaches are node-specific

thanks @torotil

  1. Applied the #141 patch ;
  2. Created new french node with field collections ;
  3. Created translation english node, modified field collections values ;

====> French (original) node field collection values were english's ones. / Field collections IDs were the same.

:(

Status:Reviewed & tested by the community» Needs work

:(
#146 means its NW

@gregory_kapustin: I've just tried exactly that and I can't reproduce your problem. Are you sure you've applied the patch correctly?

@torotil sorry I just counter-checked and problem's still there. Drupal 7-22.

Did it work on your installation ? New translation node ===> New field collection items ids ?

Yes it worked fine on my installation: node in one language with a field_collection, translate node -> add new translation -> save: The field_collections have different item_ids and I can change their contents independently.

How exactly do you create the translation?

… and could you post the code of field_collection_field_presave() in the version you are using?

Hi,
_presave has $force_new_entity = !empty($host_entity->is_new); and

        if ($force_new_entity) {
          $entity->item_id = NULL;
          $entity->revision_id = NULL;
          $entity->is_new = TRUE;
        }

I translate with node/add/MYCONTENTTYPE?translation=NID&target=en.

Whole _presave is

function field_collection_field_presave($host_entity_type, $host_entity, $field, $instance, $langcode, &$items) {
  $force_new_entity = !empty($host_entity->is_new);
  foreach ($items as &$item) {
    // In case the entity has been changed / created, save it and set the id.
    // If the host entity creates a new revision, save new item-revisions as
    // well.
    if (isset($item['entity']) || !empty($host_entity->revision)) {
      if ($entity = field_collection_field_get_entity($item)) {
        if ($force_new_entity) {
          $entity->item_id = NULL;
          $entity->revision_id = NULL;
          $entity->is_new = TRUE;
        }
        if (!empty($entity->is_new)) {
          $entity->setHostEntity($host_entity_type, $host_entity, LANGUAGE_NONE, FALSE);
        }
        // If the host entity is saved as new revision, do the same for the item.
        if (!empty($host_entity->revision)) {
          $entity->revision = TRUE;
          $is_default = entity_revision_is_default($host_entity_type, $host_entity);
          // If an entity type does not support saving non-default entities,
          // assume it will be saved as default.
          if (!isset($is_default) || $is_default) {
            $entity->default_revision = TRUE;
            $entity->archived = FALSE;
          }
        }
        $entity->save(TRUE);
        $item = array(
          'value' => $entity->item_id,
          'revision_id' => $entity->revision_id,
        );
      }
    }
  }
}

Ok, then I'm at a loss: It works for me exactly like that.

It seems that in your setup $node->is_new is not set although in my setups it always is set on node/add/…

… and node_save() has …

// Determine if we will be inserting a new node.
if (!isset($node->is_new)) {
  $node->is_new = empty($node->nid);
}

@gregory_kapustin: could you run the unit-test that's included in the patch?

Nevermind, it worked on a fresh install. I'll find what was troubling on my website, but it must not delay the rtbc.

Status:Needs work» Reviewed & tested by the community

Setting to RTBC again due to #154.

Nevermind, it worked on a fresh install. I'll find what was troubling on my website, but it must not delay the rtbc.

Thanks for testing, anyway!

StatusFileSize
new683 bytes
FAILED: [[SimpleTest]]: [MySQL] Invalid patch format in field_collection-suppoer_content_translation-1316162-156.patch.
[ View ]

Got it. I dpm'd $host_entity on field_presave, and, as weird as it is, the node entity when I add a translation to a node, "is_new" is not set on the host.

So I bypassed it with

  $force_new_entity = !empty($host_entity->is_new) || !$host_entity->nid;

Of course, it's not compatible with others entity types...... I give you my patch anyway.

@gregory_kapustin what version of drupal core / i18n_node are you using? In my tests $node->is_new was always set.

Drupal 7.22, i18n 7.x-1.8

Status:Reviewed & tested by the community» Needs work

The last submitted patch, field_collection-suppoer_content_translation-1316162-156.patch, failed testing.

Could you get a backtrace for such calls where this happens? This would be really helpful!

Something like:

if ($host_entity_type == 'node' && !$host_entity->nid && !$host_entity->is_new) {
  dpm(debug_backtrace());
}

might help …

Hello fellow Drupalistas

When I save my node with an unlimited field collection on one language, it synchronises with the other language.
I tried every patch on this issue list and on https://drupal.org/node/1683784
But nothing is resolving my problem.

I started using the dev version in hope of finding a solution.
Aren't there any clear instructions how to get it translated?

Thank you so much.

I solved my own problem.
There was something wrong in the /admin/config/regional/language/configure.
It now has a "Content language detection" section...

- Order of language detection methods for content. If a version of content is available in the detected language, it will be displayed.
I only had enable some of them.

Maybe this information could help somebody else.

tested with a fc (unlimited values), but can not confirm #141 works

Problems encountered:

Adding a new translation (update: also when editing the original content)

Expected result:
node form inheriting the original field collection values
Actual result:
node form showing empty field collection items, matching the count of the original language version.

Removing field collection item on node edit from (add translation)

Expected result:
fc item removed from multi value form item.
Actual result:
AJAX callback fails

An AJAX HTTP request terminated abnormally.
Debugging information follows.
Path: /i18ntest/de/field_collection/ajax
StatusText: n/a
ResponseText:
Error
Error message
Notice: Undefined index: field in field_widget_field() (line 578 of /modules/field/field.form.inc).
Notice: Undefined index: field in field_widget_field() (line 578 of /modules/field/field.form.inc).
Notice: Undefined index: instance in field_widget_instance() (line 603 of /modules/field/field.form.inc).
Notice: Undefined index: instance in field_widget_instance() (line 603 of /modules/field/field.form.inc).
Notice: Undefined index: field in field_widget_field() (line 578 of /modules/field/field.form.inc).
Notice: Undefined index: field in field_widget_field() (line 578 of /modules/field/field.form.inc).
Notice: Undefined index: instance in field_widget_instance() (line 603 of /modules/field/field.form.inc).
Notice: Undefined index: instance in field_widget_instance() (line 603 of /modules/field/field.form.inc).
Notice: Undefined offset: 1 in field_collection_field_widget_embed_validate() (line 1666 of /modules/field_collection/field_collection.module).
EntityMalformedException: Missing bundle property on entity of type field_collection_item. in entity_extract_ids() (line 7693 of /includes/common.inc).
The website encountered an unexpected error. Please try again later.   
ReadyState: undefined

Environment:
Drupal 7.23 (standard install)
Entity 7.x-1.2
Field Collection 7.x-1.0-beta5+1-dev
Entity Translation 7.x-1.0-beta3

That said, thanks to everyone working on the issue and providing feedback and fixes.
Field Collections are a very powerful tool for Sitebuilders and the i18n incompatibility is a major blocker.

@cjoy
Concerning your newly created translations, I bypassed the problem with that patch.

@gregory_kapustin
thank you - I just realised that the same problematic behaviour can be observed when editing the original content, so I assume the issue is more deeply rooted or I have missed something elementary here.

I was assuming that patch #141 does not rely on other patches or modules (such as node_clone). If that is not so, it would be really helpful if someone could provide a detailed description on how to reproduce a working test case for this fix with a vanilla Drupal install.

@cjoy @gregory_kapustin: I have exactly the inverse problem: I can't reproduce your problems.

I'm testing on current versions drupal 7.23, i18n 1.10, field_collection-dev + patch from #141. Two languages, one field_collection (unlimited) containing one text field (unlimited), content type with multilingual "enabled with translation".

I create a node in the first language with multiple field_collection items with one or more entries for the text-field. Then I go to Translate -> add translation. I can delete, modify, … all values without error independently from the others.

Are you using additional modules that might play a role? Can you try to reproduce this on a minimal installation? Can you try to get a backtrace like described in #160.

Regarding #163: This seems like an unrelated issue. This is about i18n_node and not about entity_translation.

@torotil
you are right - sorry for adding confusion here.

I tested it again on a vanilla Drupal install using i18n instead of entity_translation and the patch posted in #141.
Unfortunately, it does not work as expected either.

Environment:
Drupal 7.23 (standard install)
Field collection 7.x-1.0-beta5+1-dev + patch #141
Internationalization (i18n) 7.x-1.10
Multilingual content (i18n_node) 7.x-1.10

Test case
Node with a field collection (unlimited values) containing an image field and a text field

Problem
Editing the field collection items in the translated node alters the original field collection.
The translated node references the same field collection entity as the original.

Condition to reproduce
The above problem occurs only when "Create new revision" is not checked for the content type.

Workarround
Enable "Create new revision" when creating the host entity and/or translations.

@cjoy does the newly introduced unit-test (included in the patch from #141 work for you? Could you try to get a backtrace by putting something like #160 in your field_collection_field_presave()?

This is exactly what I'd expect to happen if the patch wasn't applied …

I'm afraid I fail to wrap my head around how to execute that unit test.

As for the debug info you requested:
I stepped through field_collection_field_presave() and the only difference to be noted is that the following block is fully executed for adding a translation _with_ revisions enabled and not executed otherwise:

<?php
if (!empty($host_entity->revision)) {
         
$entity->revision = TRUE;
         
$is_default = entity_revision_is_default($host_entity_type, $host_entity);
         
// If an entity type does not support saving non-default entities,
          // assume it will be saved as default.
         
if (!isset($is_default) || $is_default) {
           
$entity->default_revision = TRUE;
           
$entity->archived = FALSE;
          }
        }
?>

$force_new_entity remains FALSE in all scenarios.

Re @#152

This happens after field_attach_presave('node', $node); though:/

Status:Needs work» Needs review
StatusFileSize
new1.18 KB
new2.51 KB
FAILED: [[SimpleTest]]: [MySQL] 98 pass(es), 0 fail(s), and 1 exception(s).
[ View ]

thats the best i can come up

interdiff vs #141

Status:Needs review» Needs work

The last submitted patch, field_collection-support_content_translation-1316162-171.patch, failed testing.

Status:Needs work» Needs review
StatusFileSize
new2.52 KB
PASSED: [[SimpleTest]]: [MySQL] 135 pass(es).
[ View ]
new1.13 KB

yes that was stupid..$host_entity != $entity :P

@cjoy take a look at https://drupal.org/node/291740

@ParisLiakos: Could you provide a simpletest (that emulates node translation) that fails with #141 but works with #173?

StatusFileSize
new6.55 KB
PASSED: [[SimpleTest]]: [MySQL] 161 pass(es).
[ View ]
new6.25 KB
FAILED: [[SimpleTest]]: [MySQL] 160 pass(es), 1 fail(s), and 0 exception(s).
[ View ]
new4.17 KB

sure, i think that should do it

StatusFileSize
new1013 bytes
new7.06 KB
PASSED: [[SimpleTest]]: [MySQL] 161 pass(es).
[ View ]

and a small fix, plus README.txt update

@ParisLiakos: Where is field_attach_presave() called before $node->is_new is being set?

node_save has the following:

<?php
function node_save($node) {
   
// …
   
if (!isset($node->is_new)) {
     
$node->is_new = empty($node->nid);
    }
   
// …
    // Save fields.
   
$function = "field_attach_$op";
   
$function('node', $node);
   
// …
}
?>

So it can't be node_save(). What else leads to field_attach_presave() without is_new being set?

oh, i see what got you there. the $op variable is either insert or update, not presave. thats where field_attach_presave is being called:

<?php
function node_save($node) {
   
// ..
    // Thats where the field_collection_field_presave() is called.
   
field_attach_presave('node', $node);
    global
$user;
   
// Determine if we will be inserting a new node.
   
if (!isset($node->is_new)) {
     
$node->is_new = empty($node->nid);
    }
   
// …
    // Here hook_field_attach_(insert|update) are called not presave
   
$function = "field_attach_$op";
   
$function('node', $node);
   
// …
}
?>

Ok let's take a look at field_attach_insert() and field_attach_update():

<?php
function field_attach_insert($entity_type, $entity) {
 
_field_invoke_default('insert', $entity_type, $entity);
 
field_attach_presave($entity_type, $entity);
 
// …
}
function
field_attach_update($entity_type, $entity) {
 
field_attach_presave($entity_type, $entity);
 

}
?>

$op being 'update' or 'insert' is perfectly fine.

Ah now I see: I'm on a version of D7 where a patch for #1994594: hook_field_presave() not called reliably is applied. Never mind.

Status:Needs review» Reviewed & tested by the community

RTBC works for me on a vanilla Drupal install. - I'm still unsure why the unit-test works with #141 only though. But I won't hold this up any longer.

I'm still unsure why the unit-test works with #141 only though

+++ b/field_collection.test
@@ -299,6 +299,33 @@ class FieldCollectionBasicTestCase extends DrupalWebTestCase {
+    $node->is_new = TRUE;
...
+    node_save($node);
...
+    $node->is_new = TRUE;
...
+    node_save($node);

it works because you manually set the is_new to TRUE before calling node_save()

#1994594: hook_field_presave() not called reliably would be a nice link to add in the comments of node special casing

Status:Reviewed & tested by the community» Needs work

Good work - the patch seems to solve the issues around cloning field collections and even comes with tests!

As of now, the field-collection field does not properly respect different
revisions or languages of the host entity.

This got removed, but it does not look like the patch changes the behaviour around field translation? Thus, that sentence should stay or become more precises. Actually revision got solved already.

Some other minor remarks:

  1. +++ b/field_collection.test
    @@ -299,6 +299,33 @@ class FieldCollectionBasicTestCase extends DrupalWebTestCase {
    +   * This fixes #1316162

    Shouldn't be in here.

  2. +++ b/field_collection.test
    @@ -299,6 +299,33 @@ class FieldCollectionBasicTestCase extends DrupalWebTestCase {
    +    // create a copy of that node.

    Create needs to start upper-case.

  3. +++ b/field_collection.test
    @@ -299,6 +299,33 @@ class FieldCollectionBasicTestCase extends DrupalWebTestCase {
    +    // create another copy this time (needlessly) forcing a new revision.

    Here as well.

Title:Support content translationSupport content translation and host entity cloning
Status:Needs work» Needs review
StatusFileSize
new7.24 KB
PASSED: [[SimpleTest]]: [MySQL] 161 pass(es).
[ View ]

so thats good news, #1781190: Field Collection saved on presave went in, so we dont need to special case for nodes anymore.
updated patch that fixes #184

this will most likely fix #1416416: Add support for node_clone, i marked it as postponed on this one.

Patch #185 works fine on latest -dev version :-)

Status:Needs review» Needs work

+++ b/field_collection.module
@@ -892,17 +892,22 @@ function field_collection_field_settings_form($field, $instance) {
+        // If the host entity is new, it means it is being cloned, thus we
+        // need to clone the field collection entity as well.
...
+        $entity->revision_id = NULL;

I was about to commit this, then I figured it's not complete:
1. The comment says the host entity is being cloned, but a regular insert could look the same. -> It's being cloned when we have an field collection entity in there that's not new, but the host is suddenly new.
2. Then the comment says we need to clone the field collection entity, what is right - but we do not do that. We just save the same object with a new ID. However, it should do a PHP "clone" operation to ensure the new field collection entity has received a new identity - else the wrong item sits in the original un-cloned entity.
3. We need to improve tests to cover that. Best clone the node object also and then also assert that the two field collection entities do have different object identities (notIdentical) *and* IDs.

What about the case with old nodes which share the same field collection item due to the bug? Would be possible to fix them? ( ref to comment #27 and #94 )

@FiNeX I used this script to clone my field collections and attribute them to nodes ; worked fine.

StatusFileSize
new2.22 KB
new7.68 KB
FAILED: [[SimpleTest]]: [MySQL] 161 pass(es), 1 fail(s), and 0 exception(s).
[ View ]

well i got to say i am not sure i got #188 correctly, but here is an attempt..
is that what you mean?

Status:Needs work» Needs review

sigh

Status:Needs review» Needs work

The last submitted patch, field_collection-1316162-190.patch, failed testing.

Status:Needs work» Needs review
StatusFileSize
new1007 bytes
new7.72 KB
PASSED: [[SimpleTest]]: [MySQL] 162 pass(es).
[ View ]

oh yes, this caught a bug:)

Issue summary:View changes
StatusFileSize
new3.51 KB
PASSED: [[SimpleTest]]: [MySQL] 132 pass(es).
[ View ]

Here is an update hook, that tries to fixup host_entities that share one field_collection_item by copying the items. This can't work in all cases though as data might get lost permanently due to this bug.

Issue summary:View changes

Tried to update Issue summary, but it didn't work. Changes attempted:

In Problem/Motivation, change
Field collection does not support content translation properly. Multilingual sites are not able to use Field collection.
to

Field collection does not support node translation properly. Multilingual sites using the node translation method are not able to use Field collection.
Drupal 7 has two methods for translation:  the node translation method used in previous versions of Drupal, and the Field translation method that will be used in future versions of Drupal (see <a href="http://hojtsy.hu/blog/2011-jan-31/drupal-7039s-new-multilingual-systems-part-4-node-translation">Drupal 7's new multilingual systems (part 4) - Node translation</a>).  For the issue covering Field Translation, see <a href="https://drupal.org/node/1344672">Field Collection: Field translation (entity_translation) support</a>.

In Proposed resolution, change
Provide support to have Field collections be multilingual
to
Provide support to have Field collections work with note translation

@Mark_L6n: don't worry mate, I did that on your behalf ;)

...just a pointer: when you want to reference other issues use [#issue_id]. This way, when the issue node is rendered, besides the issue title it also reflects its status (color code and hover tooltip) as well. If you want to reference a specific comment in an issue, use [#issue_id-comment_number]. Examples:

[#1316162] renders like so: #1316162: Support content translation and host entity cloning

[#1316162-197] renders almost the same, but links directly to this comment here ;)

There is crossover with issue #1344672 I've rolled in these into the patch to get translation and cloning functioning albeit with some warnings.

https://drupal.org/comment/8229149#comment-8229149

What can I do if I want to localize only the parent item in a nested field collection, and want the child field collection to remain the same through all languages? (see #12)
Use case:
Field collection 1 (parent): A list of course titles that need to be localized.
Field collection 2 (child): A list of bibliography items that should be the same in all languages.

Thanks for any suggestions.
(I also use the field_collection_views module)

@ParisLiakos

I'm testing the patches from #194 with the current dev version.
When I enabled entity translation on a field collection field it doesn't seem to have any effect on the field. In the UI it still says "(all languages)" next to the field (other fields are translate-able at this point)

Update: enabling field translation on the field in the host entity (node) has the desired effect.

@miiimooo well you should probably check this issue then #1344672: Field Collection: Field translation (entity_translation) support.. this issue is not about field translation

Oops!

Issue summary:View changes

Hi - wondering if there's any update on this issue?

I'm very keen to use field collections on a site, with i18n translations.

I'm aware that this might be problematic due to this issue .. can anyone offer any advice on how to proceed?

check the patch in #194
i use it on production for months now, without problems

...hiding deprecated/past patches helps not to confuse people ;)

PS: I've left the patch at #195 by @torotil visible because from what I get it is an addition to the one at #194.

Hi guys,

Thanks for sharing these solutions -- really helpful.

I think it's worthy placing a note/disclaimer on the project's page.

@math3usmartins - what would you have the disclaimer say?

For those looking for an interim solution, I discovered https://drupal.org/project/field_collection_node_clone

I opened an issue in their issue queue to track this issue. I don't maintain that module, but it looks like it was born out of frustration from this issue.

Patch #194 works perfectly for me.

StatusFileSize
new11.54 KB
PASSED: [[SimpleTest]]: [MySQL] 162 pass(es).
[ View ]

I have combined the patches in 194 and 195 into one patch for easier patching.

Updated patch #211 seems to work great for me.

  1. +++ b/field_collection.module
    @@ -897,17 +897,25 @@ function field_collection_field_settings_form($field, $instance) {
    -    if (isset($item['entity'])) {

    Why is this check being removed? The change was made in #185. I assume the check was originally added for a reason.

  2. +++ b/field_collection.test
    @@ -299,6 +299,42 @@ class FieldCollectionBasicTestCase extends DrupalWebTestCase {
    +    list($node, $entity) = $this->createNodeWithFieldCollection();
    +
    +    // Create a copy of that node.
    +    $node->nid = NULL;
    +    $node->vid = NULL;
    +    $node->is_new = TRUE;
    +
    +    node_save($node);
    +    $item = $node->{$this->field_name}[LANGUAGE_NONE][0];
    +    $this->assertNotEqual($entity->item_id, $item['value']);

    This could do with some better variable names, and maybe some comments. $node? $entity? $item? Which is which?

    I assume $entity is the field collection? So how about $original_node, $original_field_collection, $duplicate_node etc. It wouldn't really make a difference to the test, but it would be clearer if we cloned $node before passing it to node_save too, and safer if this is refactored in the future.

Shouldn't FieldCollectionBasicTestCase have failed on #176?

Issue summary:View changes

StatusFileSize
new11.98 KB
FAILED: [[SimpleTest]]: [MySQL] 160 pass(es), 2 fail(s), and 1 exception(s).
[ View ]
new3.24 KB

I have made some changes based on the recommendation in #213.

Please Review

Status:Needs review» Needs work

The last submitted patch, 215: 1316162-fix-shared-field_collection_items-215.patch, failed testing.

Status:Needs work» Needs review
StatusFileSize
new3.27 KB
FAILED: [[SimpleTest]]: [MySQL] Unable to apply patch 1316162-fix-shared-field_collection_items-217.patch. Unable to apply patch. See the log in the details link for more information.
[ View ]
new3.27 KB

Let's try this again

Status:Needs review» Needs work

The last submitted patch, 217: 1316162-fix-shared-field_collection_items-217.patch, failed testing.

The last submitted patch, 86: field_collection-1316162-86.patch, failed testing.

The issued I had is when tranlsating a node. The field collection keep "referencing" to original node, causing an editing in one node change the value in the other. Then editor need to delete collection element and add a new one.

The patch provided in #211 fixed this for NEW CONTENT. However for existing content I still have the same issue. I guess field_collection_update_7005 should take care of this but not in my case.

Hi tilion,

this bug may lead to permanent data-loss. Namely users might overwrite content from other languages without knowing. The update hook from #211 tries to fix existing field_collections with a reasonable heuristic. It also restructures everything so that future edits don't lead to data loss. However it can't do magic. Data that's already lost will stay lost.

Hi,

I got an error while updating the module after patching with #211. It says that a table is not existing. I found out that we should check if the field_config.deleted is 0 at the beginning of field_collection_update_7005()

Alex

Tx very many! #211 fixed the bug where field collections where overwritten in translated nodes.

The last submitted patch, 86: field_collection-1316162-86.patch, failed testing.