private function ContentEntityNormalizer::denormalizeTranslation in Replication 8
Same name and namespace in other branches
- 8.2 src/Normalizer/ContentEntityNormalizer.php \Drupal\replication\Normalizer\ContentEntityNormalizer::denormalizeTranslation()
Parameters
$translation:
int $entity_id:
\string $entity_uuid:
string $entity_type_id:
$bundle_key:
$entity_type:
$id_key:
$context:
$rev:
array $revisions:
Return value
mixed
1 call to ContentEntityNormalizer::denormalizeTranslation()
- ContentEntityNormalizer::denormalize in src/
Normalizer/ ContentEntityNormalizer.php - Denormalizes data back into an object of the given class.
File
- src/
Normalizer/ ContentEntityNormalizer.php, line 321
Class
Namespace
Drupal\replication\NormalizerCode
private function denormalizeTranslation($translation, $entity_id, $entity_uuid, $entity_type_id, $bundle_key, $entity_type, $id_key, $context, $rev = null, array $revisions = []) {
// Add the _rev field to the $translation array.
if (isset($rev)) {
$translation['_rev'] = [
[
'value' => $rev,
],
];
}
if (isset($revisions['start']) && isset($revisions['ids'])) {
$translation['_rev'][0]['revisions'] = $revisions['ids'];
}
if (isset($entity_uuid)) {
$translation['uuid'][0]['value'] = $entity_uuid;
}
// We need to nest the data for the _deleted field in its Drupal-specific
// structure since it's un-nested to follow the API spec when normalized.
// @todo {@link https://www.drupal.org/node/2599938 Needs test for situation when a replication overwrites delete.}
$deleted = isset($translation['_deleted']) ? $translation['_deleted'] : FALSE;
$translation['_deleted'] = [
[
'value' => $deleted,
],
];
if ($entity_id) {
// @todo {@link https://www.drupal.org/node/2599938 Needs test.}
$translation[$id_key] = [
'value' => $entity_id,
];
}
$bundle_id = $entity_type_id;
if ($entity_type
->hasKey('bundle')) {
if (!empty($translation[$bundle_key][0]['value'])) {
// Add bundle info when entity is not new.
$bundle_id = $translation[$bundle_key][0]['value'];
$translation[$bundle_key] = $bundle_id;
}
elseif (!empty($translation[$bundle_key][0]['target_id'])) {
// Add bundle info when entity is new.
$bundle_id = $translation[$bundle_key][0]['target_id'];
$translation[$bundle_key] = $bundle_id;
}
}
// Denormalize entity reference fields.
foreach ($translation as $field_name => $field_info) {
if (!is_array($field_info)) {
continue;
}
foreach ($field_info as $delta => $item) {
if (!is_array($item)) {
continue;
}
if (isset($item['target_uuid'])) {
$translation[$field_name][$delta] = $item;
$fields = $this->entityManager
->getFieldDefinitions($entity_type_id, $bundle_id);
// Figure out what bundle we should use when creating the stub.
$settings = $fields[$field_name]
->getSettings();
// Find the target entity type and target bundle IDs and figure out if
// the referenced entity exists or not.
$target_entity_uuid = $item['target_uuid'];
// Denormalize link field type as an entity reference field if it
// has info about 'target_uuid' and 'entity_type_id'. These are used
// to denormalize 'uri' in formats like 'entity:ENTITY_TYPE/ID'.
$type = $fields[$field_name]
->getType();
if ($type == 'link' && isset($item['entity_type_id'])) {
$target_entity_type_id = $item['entity_type_id'];
}
else {
$target_entity_type_id = $settings['target_type'];
}
if ($target_entity_type_id === 'user') {
$translation[$field_name] = $this->usersMapping
->mapReferenceField($translation, $field_name);
continue;
}
if (isset($settings['handler_settings']['target_bundles'])) {
$target_bundle_id = reset($settings['handler_settings']['target_bundles']);
}
else {
// @todo: Update when {@link https://www.drupal.org/node/2412569
// this setting is configurable}.
$bundles = $this->entityManager
->getBundleInfo($target_entity_type_id);
$target_bundle_id = key($bundles);
}
$target_entity = null;
$uuid_index = isset($context['workspace']) && $context['workspace'] instanceof WorkspaceInterface ? $this->indexFactory
->get('multiversion.entity_index.uuid', $context['workspace']) : $this->indexFactory
->get('multiversion.entity_index.uuid');
if ($target_entity_info = $uuid_index
->get($target_entity_uuid)) {
$target_entity = $this->entityManager
->getStorage($target_entity_info['entity_type_id'])
->load($target_entity_info['entity_id']);
}
// Try to get real bundle.
if (!empty($item['entity_type_id'])) {
$bundle_key = $this->entityManager
->getStorage($item['entity_type_id'])
->getEntityType()
->getKey('bundle');
if (!empty($item[$bundle_key])) {
$target_bundle_id = $item[$bundle_key];
}
}
// This set the correct uri for link field if the target entity
// already exists.
if ($type == 'link' && $target_entity) {
$id = $target_entity
->id();
$translation[$field_name][$delta]['uri'] = "entity:{$target_entity_type_id}/{$id}";
}
elseif ($target_entity) {
$translation[$field_name][$delta]['target_id'] = $target_entity
->id();
// Special handling for Entity Reference Revisions, it needs the
// revision ID in addition to the primary entity ID.
if ($type === 'entity_reference_revisions') {
$revision_key = $target_entity
->getEntityType()
->getKey('revision');
$translation[$field_name][$delta]['target_revision_id'] = $target_entity->{$revision_key}->value;
}
}
else {
$options['target_type'] = $target_entity_type_id;
if (isset($settings['handler_settings'])) {
$options['handler_settings'] = $settings['handler_settings'];
}
/** @var \Drupal\Core\Entity\EntityReferenceSelection\SelectionWithAutocreateInterface $selection_instance */
$selection_instance = $this->selectionManager
->getInstance($options);
// We use a temporary label and entity owner ID as this will be
// backfilled later anyhow, when the real entity comes around.
$target_entity = $selection_instance
->createNewEntity($target_entity_type_id, $target_bundle_id, rand(), 1);
if (is_subclass_of($target_entity
->getEntityType()
->getStorageClass(), ContentEntityStorageInterface::class)) {
// Set the target workspace if we have it in context.
if (isset($context['workspace']) && $context['workspace'] instanceof WorkspaceInterface && $target_entity
->getEntityType()
->get('workspace') !== FALSE) {
$target_entity->workspace->target_id = $context['workspace']
->id();
}
// Set the UUID to what we received to ensure it gets updated when
// the full entity comes around later.
$target_entity->uuid->value = $target_entity_uuid;
// Indicate that this revision is a stub.
$target_entity->_rev->is_stub = TRUE;
$target_entity->langcode->value = $context['language'];
// Populate uri and filename fields if we have the info for them
// in the field item.
if ($target_entity instanceof FileInterface) {
if (isset($item['uri'])) {
$target_entity
->setFileUri($item['uri']);
}
if (isset($item['filename'])) {
$target_entity
->setFilename($item['filename']);
}
if (isset($item['filesize'])) {
$target_entity
->setSize($item['filesize']);
}
if (isset($item['filemime'])) {
$target_entity
->setMimeType($item['filemime']);
}
}
// This will ensure that stub poll_choice entities will not be saved
// in Drupal\poll\Entity\Poll:preSave()
if ($target_entity_type_id === 'poll_choice') {
$target_entity
->needsSaving(FALSE);
}
// Populate the data field.
$translation[$field_name][$delta]['target_id'] = NULL;
$translation[$field_name][$delta]['entity'] = $target_entity;
}
}
if (isset($translation[$field_name][$delta]['entity_type_id'])) {
unset($translation[$field_name][$delta]['entity_type_id']);
}
if (isset($translation[$field_name][$delta]['target_uuid'])) {
unset($translation[$field_name][$delta]['target_uuid']);
}
}
}
}
// Denormalize parent field for menu_link_content entity type.
if ($entity_type_id == 'menu_link_content' && !empty($translation['parent'][0]['value'])) {
$translation['parent'][0]['value'] = $this
->denormalizeMenuLinkParent($translation['parent'][0]['value'], $context, $translation['@context']['@language']);
}
// Unset the comment field item if CID is NULL.
if (!empty($translation['comment']) && is_array($translation['comment'])) {
foreach ($translation['comment'] as $delta => $item) {
if (empty($item['cid'])) {
unset($translation['comment'][$delta]);
}
}
}
// Exclude "name" field (the user name) for comment entity type because
// we'll change it during replication if it's a duplicate.
if ($entity_type_id == 'comment' && isset($translation['name'])) {
unset($translation['name']);
}
// Clean-up attributes we don't needs anymore.
// Remove changed info, otherwise we can get validation errors when the
// 'changed' value for existing entity is higher than for the new entity (revision).
// @see \Drupal\Core\Entity\Plugin\Validation\Constraint\EntityChangedConstraintValidator::validate().
foreach ([
'@context',
'@type',
'_id',
'_revisions',
'changed',
] as $key) {
if (isset($translation[$key])) {
unset($translation[$key]);
}
}
return $translation;
}