diff -u b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntitySerializationTest.php b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntitySerializationTest.php --- b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntitySerializationTest.php +++ b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntitySerializationTest.php @@ -148,7 +148,34 @@ $field_name = $this->entityReferenceFieldName; $user = $this->createUser(); - // Case 1: new_entity->existing_entity->parent_new_entity + // Case 1: new_entity_a->new_entity_b->new_entity_a + /** @var \Drupal\entity_test\Entity\EntityTestMul $entity_level_zero */ + $entity_level_zero = $this->entityStorage->create([ + 'name' => 'entity zero', + 'user_id' => $user->id(), + 'language' => 'en', + ]); + $entity_level_one = $entity_level_zero->createDuplicate(); + $entity_level_one->setName('entity one'); + + // Create a circular reference, where the parent entity is referenced at the + // end of the chain back again with the same object reference as at the + // beginning of the chain. + $entity_level_zero->$field_name->appendItem($entity_level_one); + $entity_level_one->$field_name->appendItem($entity_level_zero); + + // Make sure all the entities are initialized in the structure, otherwise + // they will not be contained in the serialization. + $entity_level_zero->$field_name->entity->$field_name->entity; + + // Now serialize the entity structure through deep serialization. + $entity_level_zero->setDeepSerialization(TRUE); + $serialized_main_entity = serialize($entity_level_zero); + $this->assertEquals(1, substr_count($serialized_main_entity, 'entity zero')); + $this->assertEquals(1, substr_count($serialized_main_entity, 'entity one')); + + + // Case 2: existing_entity_a->existing_entity_b->existing_entity_a_cloned /** @var \Drupal\entity_test\Entity\EntityTestMul $entity_level_zero */ $entity_level_zero = $this->entityStorage->create([ 'name' => 'entity zero', @@ -160,7 +187,6 @@ $entity_level_one->setName('entity one'); $entity_level_one->save(); - // Case 1: // Create a circular reference, where the parent entity is referenced at the // end of the chain back again with a different object reference than the // one at the beginning of the chain. @@ -182,7 +208,7 @@ $this->assertEquals(1, substr_count($serialized_main_entity, 'entity one')); - // Case 2: + // Case 3: existing_entity_a->existing_entity_b->existing_entity_a // Reset the entities for the next test. $entity_level_zero = $this->entityStorage->loadUnchanged($entity_level_zero->id()); $entity_level_one = $this->entityStorage->loadUnchanged($entity_level_one->id()); @@ -202,6 +228,57 @@ $serialized_main_entity = serialize($entity_level_zero); $this->assertEquals(2, substr_count($serialized_main_entity, 'entity zero')); $this->assertEquals(2, substr_count($serialized_main_entity, 'entity one')); + + + // Case 4 : Like the previous case, but now show that no matter how deep a + // nested structure with circular references is initialized the serialized + // string will remain the same and will contain the serialized values to the + // same amount as when the structure is not initialized that deep. + + // Reset the entities for the next test. + $entity_level_zero = $this->entityStorage->loadUnchanged($entity_level_zero->id()); + $entity_level_one = $this->entityStorage->loadUnchanged($entity_level_one->id()); + + // Create a circular reference, where the parent entity is referenced at the + // end of the chain back again with the same object reference as at the + // beginning of the chain. + $entity_level_zero->$field_name->appendItem($entity_level_one); + $entity_level_one->$field_name->appendItem($entity_level_zero); + + // Make sure all the entities are initialized in the structure, otherwise + // they will not be contained in the serialization. + $entity_level_zero->$field_name->entity->$field_name->entity; + + // Now serialize the entity structure through deep serialization. + $entity_level_zero->setDeepSerialization(TRUE); + $serialized_main_entity_case_4a = serialize($entity_level_zero); + $this->assertEquals(2, substr_count($serialized_main_entity_case_4a, 'entity zero')); + $this->assertEquals(2, substr_count($serialized_main_entity_case_4a, 'entity one')); + + // Make sure all the entities are initialized in the structure, otherwise + // they will not be contained in the serialization. + $entity_level_zero->$field_name->entity->$field_name->entity->$field_name->entity->$field_name->entity; + + // Now serialize the entity structure through deep serialization. + $entity_level_zero->setDeepSerialization(TRUE); + $serialized_main_entity_case_4b = serialize($entity_level_zero); + $this->assertEquals(2, substr_count($serialized_main_entity_case_4b, 'entity zero')); + $this->assertEquals(2, substr_count($serialized_main_entity_case_4b, 'entity one')); + + // Make sure all the entities are initialized in the structure, otherwise + // they will not be contained in the serialization. + $entity_level_zero->$field_name->entity->$field_name->entity->$field_name->entity->$field_name->entity->$field_name->entity->$field_name->entity; + + // Now serialize the entity structure through deep serialization. + $entity_level_zero->setDeepSerialization(TRUE); + $serialized_main_entity_case_4c = serialize($entity_level_zero); + $this->assertEquals(2, substr_count($serialized_main_entity_case_4c, 'entity zero')); + $this->assertEquals(2, substr_count($serialized_main_entity_case_4c, 'entity one')); + + // Assert that the serialization result does not depend on how deep the + // nested structure with circular references is initialized. + $this->assertEquals($serialized_main_entity_case_4a, $serialized_main_entity_case_4b); + $this->assertEquals($serialized_main_entity_case_4b, $serialized_main_entity_case_4c); } }