function FieldTranslationSynchronizer::synchronizeFields

Same name in other branches
  1. 8.9.x core/modules/content_translation/src/FieldTranslationSynchronizer.php \Drupal\content_translation\FieldTranslationSynchronizer::synchronizeFields()
  2. 10 core/modules/content_translation/src/FieldTranslationSynchronizer.php \Drupal\content_translation\FieldTranslationSynchronizer::synchronizeFields()
  3. 11.x core/modules/content_translation/src/FieldTranslationSynchronizer.php \Drupal\content_translation\FieldTranslationSynchronizer::synchronizeFields()

Overrides FieldTranslationSynchronizerInterface::synchronizeFields

File

core/modules/content_translation/src/FieldTranslationSynchronizer.php, line 79

Class

FieldTranslationSynchronizer
Provides field translation synchronization capabilities.

Namespace

Drupal\content_translation

Code

public function synchronizeFields(ContentEntityInterface $entity, $sync_langcode, $original_langcode = NULL) {
    $translations = $entity->getTranslationLanguages();
    // If we have no information about what to sync to, if we are creating a new
    // entity, if we have no translations for the current entity and we are not
    // creating one, then there is nothing to synchronize.
    if (empty($sync_langcode) || $entity->isNew() || count($translations) < 2) {
        return;
    }
    // If the entity language is being changed there is nothing to synchronize.
    $entity_unchanged = $this->getOriginalEntity($entity);
    if ($entity->getUntranslated()
        ->language()
        ->getId() != $entity_unchanged->getUntranslated()
        ->language()
        ->getId()) {
        return;
    }
    if ($entity->isNewRevision()) {
        if ($entity->isDefaultTranslationAffectedOnly()) {
            // If changes to untranslatable fields are configured to affect only the
            // default translation, we need to skip synchronization in pending
            // revisions, otherwise multiple translations would be affected.
            if (!$entity->isDefaultRevision()) {
                return;
            }
            else {
                $sync_langcode = $entity->getUntranslated()
                    ->language()
                    ->getId();
            }
        }
        elseif ($entity->isDefaultRevision()) {
            // If a new default revision is being saved, but a newer default
            // revision was created meanwhile, use any other translation as source
            // for synchronization, since that will have been merged from the
            // default revision. In this case the actual language does not matter as
            // synchronized properties are the same for all the translations in the
            // default revision.
            
            /** @var \Drupal\Core\Entity\ContentEntityInterface $default_revision */
            $default_revision = $this->entityTypeManager
                ->getStorage($entity->getEntityTypeId())
                ->load($entity->id());
            if ($default_revision->getLoadedRevisionId() !== $entity->getLoadedRevisionId()) {
                $other_langcodes = array_diff_key($default_revision->getTranslationLanguages(), [
                    $sync_langcode => FALSE,
                ]);
                if ($other_langcodes) {
                    $sync_langcode = key($other_langcodes);
                }
            }
        }
    }
    
    /** @var \Drupal\Core\Field\FieldItemListInterface $items */
    foreach ($entity as $field_name => $items) {
        $field_definition = $items->getFieldDefinition();
        $field_type_definition = $this->fieldTypeManager
            ->getDefinition($field_definition->getType());
        $column_groups = $field_type_definition['column_groups'];
        // Sync if the field is translatable, not empty, and the synchronization
        // setting is enabled.
        if (($translation_sync = $this->getFieldSynchronizationSettings($field_definition)) && !$items->isEmpty()) {
            // Retrieve all the untranslatable column groups and merge them into
            // single list.
            $groups = array_keys(array_diff($translation_sync, array_filter($translation_sync)));
            // If a group was selected has the require_all_groups_for_translation
            // flag set, there are no untranslatable columns. This is done because
            // the UI adds JavaScript that disables the other checkboxes, so their
            // values are not saved.
            foreach (array_filter($translation_sync) as $group) {
                if (!empty($column_groups[$group]['require_all_groups_for_translation'])) {
                    $groups = [];
                    break;
                }
            }
            if (!empty($groups)) {
                $columns = [];
                foreach ($groups as $group) {
                    $info = $column_groups[$group];
                    // A missing 'columns' key indicates we have a single-column group.
                    $columns = array_merge($columns, $info['columns'] ?? [
                        $group,
                    ]);
                }
                if (!empty($columns)) {
                    $values = [];
                    foreach ($translations as $langcode => $language) {
                        $values[$langcode] = $entity->getTranslation($langcode)
                            ->get($field_name)
                            ->getValue();
                    }
                    // If a translation is being created, the original values should be
                    // used as the unchanged items. In fact there are no unchanged items
                    // to check against.
                    $langcode = $original_langcode ?: $sync_langcode;
                    $unchanged_items = $entity_unchanged->getTranslation($langcode)
                        ->get($field_name)
                        ->getValue();
                    $this->synchronizeItems($values, $unchanged_items, $sync_langcode, array_keys($translations), $columns);
                    foreach ($translations as $langcode => $language) {
                        $entity->getTranslation($langcode)
                            ->get($field_name)
                            ->setValue($values[$langcode]);
                    }
                }
            }
        }
    }
}

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.