Issue #2124677 by damiankloip, juampynr, chr.fritsch, klausi: Expose URI in file fields when serializing an object
parent
fb8e894caf
commit
ba447d77ab
|
@ -21,6 +21,10 @@ services:
|
||||||
class: Drupal\serialization\Normalizer\ComplexDataNormalizer
|
class: Drupal\serialization\Normalizer\ComplexDataNormalizer
|
||||||
tags:
|
tags:
|
||||||
- { name: normalizer }
|
- { name: normalizer }
|
||||||
|
serializer.normalizer.entity_reference_field_item:
|
||||||
|
class: Drupal\serialization\Normalizer\EntityReferenceFieldItemNormalizer
|
||||||
|
tags:
|
||||||
|
- { name: normalizer, priority: 10 }
|
||||||
serializer.normalizer.list:
|
serializer.normalizer.list:
|
||||||
class: Drupal\serialization\Normalizer\ListNormalizer
|
class: Drupal\serialization\Normalizer\ListNormalizer
|
||||||
tags:
|
tags:
|
||||||
|
|
|
@ -0,0 +1,41 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\serialization\Normalizer\FileFieldItemNormalizer.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\serialization\Normalizer;
|
||||||
|
|
||||||
|
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds the file URI to embedded file entities.
|
||||||
|
*/
|
||||||
|
class EntityReferenceFieldItemNormalizer extends ComplexDataNormalizer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The interface or class that this Normalizer supports.
|
||||||
|
*
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $supportedInterfaceOrClass = EntityReferenceItem::class;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function normalize($field_item, $format = NULL, array $context = []) {
|
||||||
|
$values = parent::normalize($field_item, $format, $context);
|
||||||
|
|
||||||
|
// Add a 'url' value if there is a reference and a canonical URL. Hard code
|
||||||
|
// 'canonical' here as config entities override the default $rel parameter
|
||||||
|
// value to 'edit-form.
|
||||||
|
/** @var \Drupal\Core\Entity\EntityInterface $entity */
|
||||||
|
if (($entity = $field_item->get('entity')->getValue()) && ($url = $entity->url('canonical'))) {
|
||||||
|
$values['url'] = $url;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $values;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -39,6 +39,13 @@ class EntitySerializationTest extends NormalizerTestBase {
|
||||||
*/
|
*/
|
||||||
protected $entity;
|
protected $entity;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The test user.
|
||||||
|
*
|
||||||
|
* @var \Drupal\user\Entity\User
|
||||||
|
*/
|
||||||
|
protected $user;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The serializer service.
|
* The serializer service.
|
||||||
*
|
*
|
||||||
|
@ -58,10 +65,19 @@ class EntitySerializationTest extends NormalizerTestBase {
|
||||||
|
|
||||||
// User create needs sequence table.
|
// User create needs sequence table.
|
||||||
$this->installSchema('system', array('sequences'));
|
$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.
|
// Create a test entity to serialize.
|
||||||
$this->values = array(
|
$this->values = array(
|
||||||
'name' => $this->randomMachineName(),
|
'name' => $this->randomMachineName(),
|
||||||
'user_id' => \Drupal::currentUser()->id(),
|
'user_id' => $this->user->id(),
|
||||||
'field_test_text' => array(
|
'field_test_text' => array(
|
||||||
'value' => $this->randomMachineName(),
|
'value' => $this->randomMachineName(),
|
||||||
'format' => 'full_html',
|
'format' => 'full_html',
|
||||||
|
@ -99,7 +115,10 @@ class EntitySerializationTest extends NormalizerTestBase {
|
||||||
array('value' => $this->entity->created->value),
|
array('value' => $this->entity->created->value),
|
||||||
),
|
),
|
||||||
'user_id' => array(
|
'user_id' => array(
|
||||||
array('target_id' => $this->values['user_id']),
|
array(
|
||||||
|
'target_id' => $this->user->id(),
|
||||||
|
'url' => $this->user->url(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
'revision_id' => array(
|
'revision_id' => array(
|
||||||
array('value' => 1),
|
array('value' => 1),
|
||||||
|
@ -128,22 +147,15 @@ class EntitySerializationTest extends NormalizerTestBase {
|
||||||
* override some default access controls.
|
* override some default access controls.
|
||||||
*/
|
*/
|
||||||
public function testUserNormalize() {
|
public function testUserNormalize() {
|
||||||
$account = User::create([
|
|
||||||
'name' => 'serialization_test_user',
|
|
||||||
'mail' => 'foo@example.com',
|
|
||||||
'pass' => '123456',
|
|
||||||
]);
|
|
||||||
$account->save();
|
|
||||||
|
|
||||||
// Test password isn't available.
|
// 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('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');
|
$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
|
// Test again using our test user, so that our access control override will
|
||||||
// allow password viewing.
|
// 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
|
// The key 'pass' will now exist, but the password value should be
|
||||||
// normalized to NULL.
|
// normalized to NULL.
|
||||||
|
@ -179,7 +191,7 @@ class EntitySerializationTest extends NormalizerTestBase {
|
||||||
'name' => '<name><value>' . $this->values['name'] . '</value></name>',
|
'name' => '<name><value>' . $this->values['name'] . '</value></name>',
|
||||||
'type' => '<type><value>entity_test_mulrev</value></type>',
|
'type' => '<type><value>entity_test_mulrev</value></type>',
|
||||||
'created' => '<created><value>' . $this->entity->created->value . '</value></created>',
|
'created' => '<created><value>' . $this->entity->created->value . '</value></created>',
|
||||||
'user_id' => '<user_id><target_id>' . $this->values['user_id'] . '</target_id></user_id>',
|
'user_id' => '<user_id><target_id>' . $this->user->id() . '</target_id><url>' . $this->user->url() . '</url></user_id>',
|
||||||
'revision_id' => '<revision_id><value>' . $this->entity->getRevisionId() . '</value></revision_id>',
|
'revision_id' => '<revision_id><value>' . $this->entity->getRevisionId() . '</value></revision_id>',
|
||||||
'default_langcode' => '<default_langcode><value>1</value></default_langcode>',
|
'default_langcode' => '<default_langcode><value>1</value></default_langcode>',
|
||||||
'field_test_text' => '<field_test_text><value>' . $this->values['field_test_text']['value'] . '</value><format>' . $this->values['field_test_text']['format'] . '</format></field_test_text>',
|
'field_test_text' => '<field_test_text><value>' . $this->values['field_test_text']['value'] . '</value><format>' . $this->values['field_test_text']['format'] . '</format></field_test_text>',
|
||||||
|
|
|
@ -0,0 +1,121 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Contains \Drupal\Tests\serialization\Unit\Normalizer\EntityReferenceFieldItemNormalizerTest.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Drupal\Tests\serialization\Unit\Normalizer;
|
||||||
|
|
||||||
|
use Drupal\Core\Entity\EntityInterface;
|
||||||
|
use Drupal\Core\TypedData\TypedDataInterface;
|
||||||
|
use Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem;
|
||||||
|
use Drupal\serialization\Normalizer\EntityReferenceFieldItemNormalizer;
|
||||||
|
use Drupal\Tests\UnitTestCase;
|
||||||
|
use Prophecy\Argument;
|
||||||
|
use Symfony\Component\Serializer\Serializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @coversDefaultClass \Drupal\serialization\Normalizer\EntityReferenceFieldItemNormalizer
|
||||||
|
* @group serialization
|
||||||
|
*/
|
||||||
|
class EntityReferenceFieldItemNormalizerTest extends UnitTestCase {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mock serializer.
|
||||||
|
*
|
||||||
|
* @var \Symfony\Component\Serializer\SerializerInterface|\Prophecy\Prophecy\ObjectProphecy
|
||||||
|
*/
|
||||||
|
protected $serializer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The normalizer under test.
|
||||||
|
*
|
||||||
|
* @var \Drupal\serialization\Normalizer\EntityReferenceFieldItemNormalizer
|
||||||
|
*/
|
||||||
|
protected $normalizer;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The mock field item.
|
||||||
|
*
|
||||||
|
* @var \Drupal\Core\Field\Plugin\Field\FieldType\EntityReferenceItem|\Prophecy\Prophecy\ObjectProphecy
|
||||||
|
*/
|
||||||
|
protected $fieldItem;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritdoc}
|
||||||
|
*/
|
||||||
|
public function setUp() {
|
||||||
|
$this->normalizer = new EntityReferenceFieldItemNormalizer();
|
||||||
|
|
||||||
|
$this->serializer = $this->prophesize(Serializer::class);
|
||||||
|
// Set up the serializer to return an entity property.
|
||||||
|
$this->serializer->normalize(Argument::cetera())
|
||||||
|
->willReturn(['value' => 'test']);
|
||||||
|
|
||||||
|
$this->normalizer->setSerializer($this->serializer->reveal());
|
||||||
|
|
||||||
|
$this->fieldItem = $this->prophesize(EntityReferenceItem::class);
|
||||||
|
$this->fieldItem->getIterator()
|
||||||
|
->willReturn(new \ArrayIterator(['target_id' => []]));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers ::supportsNormalization
|
||||||
|
*/
|
||||||
|
public function testSupportsNormalization() {
|
||||||
|
$this->assertTrue($this->normalizer->supportsNormalization($this->fieldItem->reveal()));
|
||||||
|
$this->assertFalse($this->normalizer->supportsNormalization(new \stdClass()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers ::normalize
|
||||||
|
*/
|
||||||
|
public function testNormalize() {
|
||||||
|
$test_url = '/test/100';
|
||||||
|
|
||||||
|
$entity = $this->prophesize(EntityInterface::class);
|
||||||
|
$entity->url('canonical')
|
||||||
|
->willReturn($test_url)
|
||||||
|
->shouldBeCalled();
|
||||||
|
|
||||||
|
$entity_reference = $this->prophesize(TypedDataInterface::class);
|
||||||
|
$entity_reference->getValue()
|
||||||
|
->willReturn($entity->reveal())
|
||||||
|
->shouldBeCalled();
|
||||||
|
|
||||||
|
$this->fieldItem->get('entity')
|
||||||
|
->willReturn($entity_reference)
|
||||||
|
->shouldBeCalled();
|
||||||
|
|
||||||
|
$normalized = $this->normalizer->normalize($this->fieldItem->reveal());
|
||||||
|
|
||||||
|
$expected = [
|
||||||
|
'target_id' => ['value' => 'test'],
|
||||||
|
'url' => $test_url,
|
||||||
|
];
|
||||||
|
$this->assertSame($expected, $normalized);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @covers ::normalize
|
||||||
|
*/
|
||||||
|
public function testNormalizeWithNoEntity() {
|
||||||
|
$entity_reference = $this->prophesize(TypedDataInterface::class);
|
||||||
|
$entity_reference->getValue()
|
||||||
|
->willReturn(NULL)
|
||||||
|
->shouldBeCalled();
|
||||||
|
|
||||||
|
$this->fieldItem->get('entity')
|
||||||
|
->willReturn($entity_reference->reveal())
|
||||||
|
->shouldBeCalled();
|
||||||
|
|
||||||
|
$normalized = $this->normalizer->normalize($this->fieldItem->reveal());
|
||||||
|
|
||||||
|
$expected = [
|
||||||
|
'target_id' => ['value' => 'test'],
|
||||||
|
];
|
||||||
|
$this->assertSame($expected, $normalized);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue