diff --git a/core/lib/Drupal/Core/Entity/ContentEntityBase.php b/core/lib/Drupal/Core/Entity/ContentEntityBase.php index 3e94b7d..44fe8a3 100644 --- a/core/lib/Drupal/Core/Entity/ContentEntityBase.php +++ b/core/lib/Drupal/Core/Entity/ContentEntityBase.php @@ -1094,7 +1094,8 @@ public function __clone() { // Ensure that the following properties are actually cloned by // overwriting the original references with ones pointing to copies of - // them: enforceIsNew, newRevision, loadedRevisionId and fields. + // them: enforceIsNew, newRevision, loadedRevisionId, fields, entityKeys and + // translatableEntityKeys. $enforce_is_new = $this->enforceIsNew; $this->enforceIsNew = &$enforce_is_new; @@ -1107,6 +1108,12 @@ public function __clone() { $fields = $this->fields; $this->fields = &$fields; + $entity_keys = $this->entityKeys; + $this->entityKeys = &$entity_keys; + + $translatable_entity_keys = $this->translatableEntityKeys; + $this->translatableEntityKeys = &$translatable_entity_keys; + foreach ($this->fields as $name => $values) { $this->fields[$name] = []; // Untranslatable fields may have multiple references for the same field diff --git a/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityCloneTest.php b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityCloneTest.php index 79c7f14..a0ae4d8 100644 --- a/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityCloneTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityCloneTest.php @@ -179,4 +179,41 @@ public function testNewRevisionOnCloneEntityTranslation() { $this->assertFalse($entity_translation->isNewRevision()); } + /** + * Tests modifications on entity keys of a cloned entity object. + */ + public function testEntityKeysModifications() { + // Create a test entity with a translation, which will internally trigger + // entity cloning for the new translation and create references for some of + // the entity properties. + $entity = EntityTestMulRev::create([ + 'name' => $this->randomString(), + 'language' => 'en', + ]); + $entity->addTranslation('de'); + $entity->save(); + + // Clone the entity. + $clone = clone $entity; + + // Alter a non-translatable and a translatable entity key fields of the + // cloned entity and assert that retrieving the value through the entity + // keys local cache will be different for the cloned and the original + // entity. + // We first have to call the ::uuid() and ::label() method on the original + // entity as it is going to cache the field values into the $entityKeys and + // $translatableEntityKeys properties of the entity object and we want to + // check that the cloned and the original entity aren't sharing the same + // reference to those local cache properties. + $uuid_field_name = $entity->getEntityType()->getKey('uuid'); + $this->assertFalse($entity->getFieldDefinition($uuid_field_name)->isTranslatable()); + $clone->$uuid_field_name->value = 'test-change-uuid'; + $this->assertNotEquals($entity->uuid(), $clone->uuid()); + + $label_field_name = $entity->getEntityType()->getKey('label'); + $this->assertTrue($entity->getFieldDefinition($label_field_name)->isTranslatable()); + $clone->$label_field_name->value = 'test-change-label'; + $this->assertNotEquals($entity->label(), $clone->label()); + } + }