diff --git a/core/modules/serialization/serialization.services.yml b/core/modules/serialization/serialization.services.yml index 318a90c..070a530 100644 --- a/core/modules/serialization/serialization.services.yml +++ b/core/modules/serialization/serialization.services.yml @@ -21,6 +21,10 @@ services: class: Drupal\serialization\Normalizer\ComplexDataNormalizer tags: - { name: normalizer } + serializer.normalizer.entity_reference_field_item: + class: Drupal\serialization\Normalizer\EntityReferenceFieldItemNormalizer + tags: + - { name: normalizer, priority: 10 } serializer.normalizer.list: class: Drupal\serialization\Normalizer\ListNormalizer tags: diff --git a/core/modules/serialization/src/Normalizer/EntityReferenceFieldItemNormalizer.php b/core/modules/serialization/src/Normalizer/EntityReferenceFieldItemNormalizer.php new file mode 100644 index 0000000..a08ae4a --- /dev/null +++ b/core/modules/serialization/src/Normalizer/EntityReferenceFieldItemNormalizer.php @@ -0,0 +1,39 @@ +get('entity')->getValue()) && ($url = $entity->url('canonical'))) { + $values['url'] = $url; + } + + return $values; + } + +} diff --git a/core/modules/serialization/src/Tests/EntitySerializationTest.php b/core/modules/serialization/src/Tests/EntitySerializationTest.php index bb305a7..3a9daf8 100644 --- a/core/modules/serialization/src/Tests/EntitySerializationTest.php +++ b/core/modules/serialization/src/Tests/EntitySerializationTest.php @@ -40,6 +40,13 @@ class EntitySerializationTest extends NormalizerTestBase { protected $entity; /** + * The test user. + * + * @var \Drupal\user\Entity\User + */ + protected $user; + + /** * The serializer service. * * @var \Symfony\Component\Serializer\Serializer. @@ -58,10 +65,19 @@ protected function setUp() { // User create needs sequence table. $this->installSchema('system', array('sequences')); + + // Create a test user to use as the entity owner. + $this->user = \Drupal::entityManager()->getStorage('user')->create([ + 'name' => 'serialization_test_user', + 'mail' => 'foo@example.com', + 'pass' => '123456', + ]); + $this->user->save(); + // Create a test entity to serialize. $this->values = array( 'name' => $this->randomMachineName(), - 'user_id' => \Drupal::currentUser()->id(), + 'user_id' => $this->user->id(), 'field_test_text' => array( 'value' => $this->randomMachineName(), 'format' => 'full_html', @@ -99,7 +115,10 @@ public function testNormalize() { array('value' => $this->entity->created->value), ), 'user_id' => array( - array('target_id' => $this->values['user_id']), + array( + 'target_id' => $this->user->id(), + 'url' => $this->user->url(), + ), ), 'revision_id' => array( array('value' => 1), @@ -128,22 +147,15 @@ public function testNormalize() { * override some default access controls. */ public function testUserNormalize() { - $account = User::create([ - 'name' => 'serialization_test_user', - 'mail' => 'foo@example.com', - 'pass' => '123456', - ]); - $account->save(); - // Test password isn't available. - $normalized = $this->serializer->normalize($account); + $normalized = $this->serializer->normalize($this->user); $this->assertFalse(array_key_exists('pass', $normalized), '"pass" key does not exist in normalized user'); $this->assertFalse(array_key_exists('mail', $normalized), '"mail" key does not exist in normalized user'); // Test again using our test user, so that our access control override will // allow password viewing. - $normalized = $this->serializer->normalize($account, NULL, ['account' => $account]); + $normalized = $this->serializer->normalize($this->user, NULL, ['account' => $this->user]); // The key 'pass' will now exist, but the password value should be // normalized to NULL. @@ -179,7 +191,7 @@ public function testSerialize() { 'name' => '' . $this->values['name'] . '', 'type' => 'entity_test_mulrev', 'created' => '' . $this->entity->created->value . '', - 'user_id' => '' . $this->values['user_id'] . '', + 'user_id' => '' . $this->user->id() . '' . $this->user->url() . '', 'revision_id' => '' . $this->entity->getRevisionId() . '', 'default_langcode' => '1', 'field_test_text' => '' . $this->values['field_test_text']['value'] . '' . $this->values['field_test_text']['format'] . '', diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php b/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php new file mode 100644 index 0000000..1adc99c --- /dev/null +++ b/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php @@ -0,0 +1,125 @@ +normalizer = new EntityReferenceFieldItemNormalizer(); + + $this->serializer = $this->getMockBuilder('Symfony\Component\Serializer\Serializer') + ->disableOriginalConstructor() + ->setMethods(array('normalize')) + ->getMock(); + // Set up the serializer to return an entity property. + $this->serializer->expects($this->any()) + ->method('normalize') + ->willReturn(['value' => 'test']); + + $this->normalizer->setSerializer($this->serializer); + + $this->fieldItem = $this->getMockBuilder('Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem') + ->disableOriginalConstructor() + ->getMock(); + $this->fieldItem->expects($this->any()) + ->method('getIterator') + ->willReturn(new \ArrayIterator(['target_id' => []])); + } + + /** + * @covers ::supportsNormalization + */ + public function testSupportsNormalization() { + $this->assertTrue($this->normalizer->supportsNormalization($this->fieldItem)); + $this->assertFalse($this->normalizer->supportsNormalization(new \stdClass())); + } + + /** + * @covers ::normalize + */ + public function testNormalize() { + $test_url = '/test/100'; + + $entity = $this->getMock('Drupal\Core\Entity\EntityInterface'); + $entity->expects($this->once()) + ->method('url') + ->willReturn($test_url); + + $entity_reference = $this->getMock('Drupal\Core\TypedData\TypedDataInterface'); + $entity_reference->expects($this->once()) + ->method('getValue') + ->willReturn($entity); + + $this->fieldItem->expects($this->once()) + ->method('get') + ->with('entity') + ->willReturn($entity_reference); + + $normalized = $this->normalizer->normalize($this->fieldItem); + + $expected = [ + 'target_id' => ['value' => 'test'], + 'url' => $test_url, + ]; + $this->assertSame($expected, $normalized); + } + + /** + * @covers ::normalize + */ + public function testNormalizeWithNoEntity() { + $entity_reference = $this->getMock('Drupal\Core\TypedData\TypedDataInterface'); + $entity_reference->expects($this->once()) + ->method('getValue') + ->willReturn(NULL); + + $this->fieldItem->expects($this->once()) + ->method('get') + ->with('entity') + ->willReturn($entity_reference); + + $normalized = $this->normalizer->normalize($this->fieldItem); + + $expected = [ + 'target_id' => ['value' => 'test'], + ]; + $this->assertSame($expected, $normalized); + } + +}