The entity_translation_sync function creates a $change_map to track changes given by $columns.

I've made a compound field (cardinality -1) with subfields a (text), b (int) and c (int).

The problem is that some times subfields b and/or c is either empty or contains the same value. The $change_map uses the subfield values as array keys which means that when saving three rows with identical b and/or c, only the last row is synchronized with the other translations.

Change map structure

$change_map[$column][$value]['old'] = $delta;

(I also have to use the patch in #2628094: Field synchronization only works with a single column and won't keep non synced values that set $changed to TRUE if a single field is different, which is the expected behavior)

My initial idea was to concatenate the subfield value with its delta value and use that as array keys:

$change_map[$column][$delta . $value]['old'] = $delta;

It works, as a proof of concept, but this particular solution will have a collision when
[delta = 1][b] = 11
and
[delta = 11][b] = 1
and even
[delta = 111][b] = '' if empty values are allowed.

I think however we can ensure uniqueness across any combination of delta and value if we add a non-integer character between $delta and $value like this:

$change_map[$column][$delta . '-' . $value]['old'] = $delta;

Since this operation is transient and doesn't touch the data itself, I think the patch is very safe to use.

Support from Acquia helps fund testing for Drupal Acquia logo

Comments

odegard created an issue. See original summary.

odegard’s picture

odegard’s picture

If you need this patch, it's because you have a compound field. If you have a compound field you also need the patch in #2628094: Field synchronization only works with a single column and won't keep non synced values. Please look at that issue for an updated patch and read the comments, I'm not sure how dependent patches is supposed to work.

odegard’s picture

Status: Active » Needs work

Patch fails at reordering translatable fields.

odegard’s picture

Status: Needs work » Closed (won't fix)

This will never work.

On the one hand, we need to ensure that the array keys are unique so subfield values aren't overwritten, on the other hand values need to be compared to find out if they were reordered... and you can't have both. It's my understanding that the sync function will only work when values are not empty and all are different. The patch I linked to is needed for compound fields but here you also need different values for all subfields, and they must be unique per row.

I ended up writing my own synchronization function depending on an extra id field that I could use to compare values against. It's specific to my use case (field names among others) and is not general enough to provide a patch. Closing this issue.