/** * {@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); } }