/**
  * {@inheritdoc}
  */
 public function onPresave(ContentEntityInterface $entity, $default_revision, $published_state)
 {
     // This is *probably* not necessary if configuration is setup correctly,
     // but it can't hurt.
     $entity->setNewRevision(TRUE);
     // A newly-created revision is always the default revision, or else
     // it gets lost.
     $entity->isDefaultRevision($entity->isNew() || $default_revision);
 }
 /**
  * {@inheritdoc}
  */
 public function synchronizeFields(ContentEntityInterface $entity, $sync_langcode, $original_langcode = NULL)
 {
     $translations = $entity->getTranslationLanguages();
     $field_type_manager = \Drupal::service('plugin.manager.field.field_type');
     // 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_type = $entity->getEntityTypeId();
     $entity_unchanged = isset($entity->original) ? $entity->original : $this->entityManager->getStorage($entity_type)->loadUnchanged($entity->id());
     if ($entity->getUntranslated()->language()->getId() != $entity_unchanged->getUntranslated()->language()->getId()) {
         return;
     }
     /** @var \Drupal\Core\Field\FieldItemListInterface $items */
     foreach ($entity as $field_name => $items) {
         $field_definition = $items->getFieldDefinition();
         $field_type_definition = $field_type_manager->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 ($field_definition instanceof ThirdPartySettingsInterface && $field_definition->isTranslatable() && !$items->isEmpty() && ($translation_sync = $field_definition->getThirdPartySetting('content_translation', 'translation_sync'))) {
             // Retrieve all the untranslatable column groups and merge them into
             // single list.
             $groups = array_keys(array_diff($translation_sync, array_filter($translation_sync)));
             if (!empty($groups)) {
                 $columns = array();
                 foreach ($groups as $group) {
                     $info = $column_groups[$group];
                     // A missing 'columns' key indicates we have a single-column group.
                     $columns = array_merge($columns, isset($info['columns']) ? $info['columns'] : array($group));
                 }
                 if (!empty($columns)) {
                     $values = array();
                     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]);
                     }
                 }
             }
         }
     }
 }
 /**
  * {@inheritdoc}
  */
 protected function doSaveFieldItems(ContentEntityInterface $entity, array $names = [])
 {
     $full_save = empty($names);
     $update = !$full_save || !$entity->isNew();
     if ($full_save) {
         $shared_table_fields = TRUE;
         $dedicated_table_fields = TRUE;
     } else {
         $table_mapping = $this->getTableMapping();
         $storage_definitions = $this->entityManager->getFieldStorageDefinitions($this->entityTypeId);
         $shared_table_fields = FALSE;
         $dedicated_table_fields = [];
         // Collect the name of fields to be written in dedicated tables and check
         // whether shared table records need to be updated.
         foreach ($names as $name) {
             $storage_definition = $storage_definitions[$name];
             if ($table_mapping->allowsSharedTableStorage($storage_definition)) {
                 $shared_table_fields = TRUE;
             } elseif ($table_mapping->requiresDedicatedTableStorage($storage_definition)) {
                 $dedicated_table_fields[] = $name;
             }
         }
     }
     // Update shared table records if necessary.
     if ($shared_table_fields) {
         $record = $this->mapToStorageRecord($entity->getUntranslated(), $this->baseTable);
         // Create the storage record to be saved.
         if ($update) {
             $default_revision = $entity->isDefaultRevision();
             if ($default_revision) {
                 $this->database->update($this->baseTable)->fields((array) $record)->condition($this->idKey, $record->{$this->idKey})->execute();
             }
             if ($this->revisionTable) {
                 if ($full_save) {
                     $entity->{$this->revisionKey} = $this->saveRevision($entity);
                 } else {
                     $record = $this->mapToStorageRecord($entity->getUntranslated(), $this->revisionTable);
                     $entity->preSaveRevision($this, $record);
                     $this->database->update($this->revisionTable)->fields((array) $record)->condition($this->revisionKey, $record->{$this->revisionKey})->execute();
                 }
             }
             if ($default_revision && $this->dataTable) {
                 $this->saveToSharedTables($entity);
             }
             if ($this->revisionDataTable) {
                 $new_revision = $full_save && $entity->isNewRevision();
                 $this->saveToSharedTables($entity, $this->revisionDataTable, $new_revision);
             }
         } else {
             $insert_id = $this->database->insert($this->baseTable, array('return' => Database::RETURN_INSERT_ID))->fields((array) $record)->execute();
             // Even if this is a new entity the ID key might have been set, in which
             // case we should not override the provided ID. An ID key that is not set
             // to any value is interpreted as NULL (or DEFAULT) and thus overridden.
             if (!isset($record->{$this->idKey})) {
                 $record->{$this->idKey} = $insert_id;
             }
             $entity->{$this->idKey} = (string) $record->{$this->idKey};
             if ($this->revisionTable) {
                 $record->{$this->revisionKey} = $this->saveRevision($entity);
             }
             if ($this->dataTable) {
                 $this->saveToSharedTables($entity);
             }
             if ($this->revisionDataTable) {
                 $this->saveToSharedTables($entity, $this->revisionDataTable);
             }
         }
     }
     // Update dedicated table records if necessary.
     if ($dedicated_table_fields) {
         $names = is_array($dedicated_table_fields) ? $dedicated_table_fields : [];
         $this->saveToDedicatedTables($entity, $update, $names);
     }
 }