function FieldTranslationSynchronizer::synchronizeItems
Same name in other branches
- 8.9.x core/modules/content_translation/src/FieldTranslationSynchronizer.php \Drupal\content_translation\FieldTranslationSynchronizer::synchronizeItems()
- 10 core/modules/content_translation/src/FieldTranslationSynchronizer.php \Drupal\content_translation\FieldTranslationSynchronizer::synchronizeItems()
- 11.x core/modules/content_translation/src/FieldTranslationSynchronizer.php \Drupal\content_translation\FieldTranslationSynchronizer::synchronizeItems()
Overrides FieldTranslationSynchronizerInterface::synchronizeItems
1 call to FieldTranslationSynchronizer::synchronizeItems()
- FieldTranslationSynchronizer::synchronizeFields in core/
modules/ content_translation/ src/ FieldTranslationSynchronizer.php - Performs field column synchronization on the given entity.
File
-
core/
modules/ content_translation/ src/ FieldTranslationSynchronizer.php, line 205
Class
- FieldTranslationSynchronizer
- Provides field translation synchronization capabilities.
Namespace
Drupal\content_translationCode
public function synchronizeItems(array &$values, array $unchanged_items, $sync_langcode, array $translations, array $properties) {
$source_items = $values[$sync_langcode];
// Make sure we can detect any change in the source items.
$change_map = [];
// By picking the maximum size between updated and unchanged items, we make
// sure to process also removed items.
$total = max([
count($source_items),
count($unchanged_items),
]);
// As a first step we build a map of the deltas corresponding to the column
// values to be synchronized. Recording both the old values and the new
// values will allow us to detect any change in the order of the new items
// for each column.
for ($delta = 0; $delta < $total; $delta++) {
foreach ([
'old' => $unchanged_items,
'new' => $source_items,
] as $key => $items) {
if ($item_id = $this->itemHash($items, $delta, $properties)) {
$change_map[$item_id][$key][] = $delta;
}
}
}
// Backup field values and the change map.
$original_field_values = $values;
$original_change_map = $change_map;
// Reset field values so that no spurious one is stored. Source values must
// be preserved in any case.
$values = [
$sync_langcode => $source_items,
];
// Update field translations.
foreach ($translations as $langcode) {
// We need to synchronize only values different from the source ones.
if ($langcode != $sync_langcode) {
// Reinitialize the change map as it is emptied while processing each
// language.
$change_map = $original_change_map;
// By using the maximum cardinality we ensure to process removed items.
for ($delta = 0; $delta < $total; $delta++) {
// By inspecting the map we built before we can tell whether a value
// has been created or removed. A changed value will be interpreted as
// a new value, in fact it did not exist before.
$created = TRUE;
$removed = TRUE;
$old_delta = NULL;
$new_delta = NULL;
if ($item_id = $this->itemHash($source_items, $delta, $properties)) {
if (!empty($change_map[$item_id]['old'])) {
$old_delta = array_shift($change_map[$item_id]['old']);
}
if (!empty($change_map[$item_id]['new'])) {
$new_delta = array_shift($change_map[$item_id]['new']);
}
$created = $created && !isset($old_delta);
$removed = $removed && !isset($new_delta);
}
// If an item has been removed we do not store its translations.
if ($removed) {
continue;
}
elseif ($created && !empty($original_field_values[$langcode][$delta])) {
$values[$langcode][$delta] = $this->createMergedItem($source_items[$delta], $original_field_values[$langcode][$delta], $properties);
}
elseif ($created) {
$values[$langcode][$delta] = $source_items[$delta];
}
elseif (isset($old_delta) && isset($new_delta)) {
// If for any reason the old value is not defined for the current
// language we fall back to the new source value, this way we ensure
// the new values are at least propagated to all the translations.
// If the value has only been reordered we just move the old one in
// the new position.
$item = $original_field_values[$langcode][$old_delta] ?? $source_items[$new_delta];
// When saving a default revision starting from a pending revision,
// we may have desynchronized field values, so we make sure that
// untranslatable properties are synchronized, even if in any other
// situation this would not be necessary.
$values[$langcode][$new_delta] = $this->createMergedItem($source_items[$new_delta], $item, $properties);
}
}
}
}
}
Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.