function FieldTranslationSynchronizer::synchronizeFields

Same name and namespace in other branches
  1. 11.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. 8.9.x core/modules/content_translation/src/FieldTranslationSynchronizer.php \Drupal\content_translation\FieldTranslationSynchronizer::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.