diff --git a/core/lib/Drupal/Core/Config/Schema/ArrayElement.php b/core/lib/Drupal/Core/Config/Schema/ArrayElement.php index ae96d2d6e1..b38a94b3c2 100644 --- a/core/lib/Drupal/Core/Config/Schema/ArrayElement.php +++ b/core/lib/Drupal/Core/Config/Schema/ArrayElement.php @@ -3,15 +3,12 @@ namespace Drupal\Core\Config\Schema; use Drupal\Core\TypedData\ComplexDataInterface; -use Drupal\Core\TypedData\ComplexDataWithExposedPropertiesTrait; /** * Defines a generic configuration element that contains multiple properties. */ abstract class ArrayElement extends Element implements \IteratorAggregate, TypedConfigInterface, ComplexDataInterface { - use ComplexDataWithExposedPropertiesTrait; - /** * Parsed elements. */ diff --git a/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityAdapter.php b/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityAdapter.php index 311f4080e2..4e81796dc3 100644 --- a/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityAdapter.php +++ b/core/lib/Drupal/Core/Entity/Plugin/DataType/EntityAdapter.php @@ -6,7 +6,6 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\TypedData\EntityDataDefinition; use Drupal\Core\TypedData\ComplexDataInterface; -use Drupal\Core\TypedData\ComplexDataWithExposedPropertiesTrait; use Drupal\Core\TypedData\Exception\MissingDataException; use Drupal\Core\TypedData\TypedData; @@ -28,8 +27,6 @@ * ) */ class EntityAdapter extends TypedData implements \IteratorAggregate, ComplexDataInterface { - - use ComplexDataWithExposedPropertiesTrait; /** * The wrapped entity object. * diff --git a/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php b/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php index 5b6b58b4a4..6396cb8f51 100644 --- a/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php +++ b/core/lib/Drupal/Core/TypedData/ComplexDataInterface.php @@ -102,12 +102,4 @@ public function toArray(); */ public function isEmpty(); - /** - * Gets an array of property objects for exposed properties. - * - * @return \Drupal\Core\TypedData\TypedDataInterface[] - * The exposed properties. - */ - public function getExposedProperties(); - } diff --git a/core/lib/Drupal/Core/TypedData/ComplexDataWithExposedPropertiesTrait.php b/core/lib/Drupal/Core/TypedData/ComplexDataWithExposedPropertiesTrait.php deleted file mode 100644 index 69e3d61a50..0000000000 --- a/core/lib/Drupal/Core/TypedData/ComplexDataWithExposedPropertiesTrait.php +++ /dev/null @@ -1,27 +0,0 @@ -getProperties(TRUE); - /* @var \Drupal\Core\TypedData\TypedDataInterface[] $properties */ - foreach (array_keys($properties) as $property_name) { - if (!$properties[$property_name]->getDataDefinition()->isExposed()) { - unset($properties[$property_name]); - } - } - return $properties; - } - -} diff --git a/core/lib/Drupal/Core/TypedData/DataDefinitionInterface.php b/core/lib/Drupal/Core/TypedData/DataDefinitionInterface.php index afaf4f441f..7ea68e47e6 100644 --- a/core/lib/Drupal/Core/TypedData/DataDefinitionInterface.php +++ b/core/lib/Drupal/Core/TypedData/DataDefinitionInterface.php @@ -227,7 +227,7 @@ public function addConstraint($constraint_name, $options = NULL); * @return static * The object itself for chaining. */ - public function setExposed($exposed); + public function setExposed($exposed = TRUE); /** * Determines whether the data value is exposed. diff --git a/core/lib/Drupal/Core/TypedData/ExposableDataDefinitionTrait.php b/core/lib/Drupal/Core/TypedData/ExposableDataDefinitionTrait.php index 708e40f3a9..ba47fe35c7 100644 --- a/core/lib/Drupal/Core/TypedData/ExposableDataDefinitionTrait.php +++ b/core/lib/Drupal/Core/TypedData/ExposableDataDefinitionTrait.php @@ -26,7 +26,7 @@ public function isExposed() { * * Implements setExposed() for \Drupal\Core\TypedData\DataDefinitionInterface. */ - public function setExposed($exposed) { + public function setExposed($exposed = TRUE) { $this->definition['exposed'] = $exposed; return $this; } diff --git a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php index a3b2657c9f..a95c14b30e 100644 --- a/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php +++ b/core/lib/Drupal/Core/TypedData/Plugin/DataType/Map.php @@ -2,7 +2,6 @@ namespace Drupal\Core\TypedData\Plugin\DataType; -use Drupal\Core\TypedData\ComplexDataWithExposedPropertiesTrait; use Drupal\Core\TypedData\TypedData; use Drupal\Core\TypedData\ComplexDataInterface; @@ -27,8 +26,6 @@ */ class Map extends TypedData implements \IteratorAggregate, ComplexDataInterface { - use ComplexDataWithExposedPropertiesTrait; - /** * The data definition. * diff --git a/core/lib/Drupal/Core/TypedData/TypedDataHelper.php b/core/lib/Drupal/Core/TypedData/TypedDataHelper.php new file mode 100644 index 0000000000..1df10eb252 --- /dev/null +++ b/core/lib/Drupal/Core/TypedData/TypedDataHelper.php @@ -0,0 +1,27 @@ +getProperties(TRUE), function (TypedDataInterface $property) { + return $property->getDataDefinition()->isExposed(); + }); + } + +} diff --git a/core/modules/path/tests/src/Kernel/PathItemTest.php b/core/modules/path/tests/src/Kernel/PathItemTest.php index 9a85a27958..1c7eb28ae0 100644 --- a/core/modules/path/tests/src/Kernel/PathItemTest.php +++ b/core/modules/path/tests/src/Kernel/PathItemTest.php @@ -66,10 +66,18 @@ public function testPathItem() { $node_storage->resetCache(); + // Ensure that isEmpty(), ->alias, and [0]->get('alias')->getValue() can all + // be called individually without the other methods being called. + // @see \Drupal\path\Plugin\Field\FieldType\PathItem::ensureLoaded() /** @var \Drupal\node\NodeInterface $loaded_node */ $loaded_node = $node_storage->load($node->id()); $this->assertFalse($loaded_node->get('path')->isEmpty()); + $node_storage->resetCache(); + $loaded_node = $node_storage->load($node->id()); $this->assertEquals('/foo', $loaded_node->get('path')->alias); + $node_storage->resetCache(); + $loaded_node = $node_storage->load($node->id()); + $this->assertEquals('/foo', $loaded_node->get('path')[0]->get('alias')->getValue()); $node_storage->resetCache(); $loaded_node = $node_storage->load($node->id()); diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestExposedPropertyNormalizerTest.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestExposedPropertyNormalizerTest.php index 27729afa82..5a7df055e7 100644 --- a/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestExposedPropertyNormalizerTest.php +++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestExposedPropertyNormalizerTest.php @@ -10,8 +10,6 @@ /** * Test that exposed properties are actually exposed in REST. * - * @see \Drupal\Core\TypedData\ComplexDataWithExposedPropertiesTrait - * * @group rest */ class EntityTestExposedPropertyNormalizerTest extends EntityTestResourceTestBase { diff --git a/core/modules/serialization/src/Normalizer/ComplexDataPropertiesNormalizerTrait.php b/core/modules/serialization/src/Normalizer/ComplexDataPropertiesNormalizerTrait.php index 0969629faf..8697d1ff29 100644 --- a/core/modules/serialization/src/Normalizer/ComplexDataPropertiesNormalizerTrait.php +++ b/core/modules/serialization/src/Normalizer/ComplexDataPropertiesNormalizerTrait.php @@ -4,6 +4,7 @@ use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\TypedData\ComplexDataInterface; +use Drupal\Core\TypedData\TypedDataHelper; /** * Normalization methods for complex data properties. @@ -25,7 +26,7 @@ */ protected function normalizeProperties(ComplexDataInterface $data, $format, array $context) { $attributes = []; - foreach ($data->getExposedProperties() as $name => $property) { + foreach (TypedDataHelper::getExposedProperties($data) as $name => $property) { $attribute = $this->serializer->normalize($property, $format, $context); if ($attribute instanceof CacheableDependencyInterface && isset($context['cacheability'])) { $context['cacheability']->addCacheableDependency($attribute); diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/ComplexDataNormalizerTest.php b/core/modules/serialization/tests/src/Unit/Normalizer/ComplexDataNormalizerTest.php index de936d7acf..5ca4726660 100644 --- a/core/modules/serialization/tests/src/Unit/Normalizer/ComplexDataNormalizerTest.php +++ b/core/modules/serialization/tests/src/Unit/Normalizer/ComplexDataNormalizerTest.php @@ -10,6 +10,7 @@ use Drupal\Core\Cache\CacheableDependencyInterface; use Drupal\Core\Cache\RefinableCacheableDependencyInterface; use Drupal\Core\TypedData\ComplexDataInterface; +use Drupal\Core\TypedData\DataDefinitionInterface; use Drupal\Core\TypedData\TypedDataInterface; use Drupal\serialization\Normalizer\ComplexDataNormalizer; use Drupal\Tests\UnitTestCase; @@ -21,6 +22,8 @@ */ class ComplexDataNormalizerTest extends UnitTestCase { + use TypedDataTestTrait; + /** * Test format string. * @@ -66,8 +69,9 @@ public function testNormalizeComplexData() { ->shouldBeCalled(); $cacheable = $cacheable->reveal(); - $property = $this->prophesize(TypedDataInterface::class); - $property = $property->reveal(); + $exposed_cacheable_property = $this->getTypedDataProperty(); + $exposed_noncacheable_property = $this->getTypedDataProperty(); + $cacheableMetaData = $this->prophesize(RefinableCacheableDependencyInterface::class); $cacheableMetaData->addCacheableDependency($cacheable) @@ -76,18 +80,22 @@ public function testNormalizeComplexData() { 'cacheability' => $cacheableMetaData->reveal(), ]; - $serializer_prophecy->normalize('A', static::TEST_FORMAT, $serialization_context) + $serializer_prophecy->normalize($exposed_noncacheable_property, static::TEST_FORMAT, $serialization_context) ->willReturn('A-normalized') ->shouldBeCalled(); - $serializer_prophecy->normalize($property, static::TEST_FORMAT, $serialization_context) + $serializer_prophecy->normalize($exposed_cacheable_property, static::TEST_FORMAT, $serialization_context) ->willReturn($cacheable) ->shouldBeCalled(); $this->normalizer->setSerializer($serializer_prophecy->reveal()); $complex_data = $this->prophesize(ComplexDataInterface::class); - $complex_data->getExposedProperties() - ->willReturn(['prop:a' => 'A', 'prop:cacheable' => $property]) + $complex_data->getProperties(TRUE) + ->willReturn([ + 'prop:a' => $exposed_noncacheable_property, + 'prop:cacheable' => $exposed_cacheable_property, + 'prop:nonexposed' => $this->getTypedDataProperty(FALSE), + ]) ->shouldBeCalled(); $normalized = $this->normalizer->normalize($complex_data->reveal(), static::TEST_FORMAT, $serialization_context); diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php b/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php index a107250865..b9a4f361ba 100644 --- a/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php +++ b/core/modules/serialization/tests/src/Unit/Normalizer/EntityReferenceFieldItemNormalizerTest.php @@ -4,6 +4,7 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Field\FieldDefinitionInterface; +use Drupal\Core\TypedData\DataDefinitionInterface; use Drupal\Core\TypedData\Plugin\DataType\StringData; use Drupal\Core\TypedData\Type\StringInterface; use Drupal\Core\TypedData\TypedDataInterface; @@ -25,6 +26,8 @@ */ class EntityReferenceFieldItemNormalizerTest extends UnitTestCase { + use TypedDataTestTrait; + /** * The mock serializer. * @@ -124,8 +127,8 @@ public function testNormalize() { ->willReturn($entity_reference) ->shouldBeCalled(); - $this->fieldItem->getExposedProperties() - ->willReturn(['target_id' => NULL]) + $this->fieldItem->getProperties(TRUE) + ->willReturn(['target_id' => $this->getTypedDataProperty()]) ->shouldBeCalled(); $normalized = $this->normalizer->normalize($this->fieldItem->reveal()); @@ -152,8 +155,8 @@ public function testNormalizeWithNoEntity() { ->willReturn($entity_reference->reveal()) ->shouldBeCalled(); - $this->fieldItem->getExposedProperties() - ->willReturn(['target_id' => NULL]) + $this->fieldItem->getProperties(TRUE) + ->willReturn(['target_id' => $this->getTypedDataProperty()]) ->shouldBeCalled(); $normalized = $this->normalizer->normalize($this->fieldItem->reveal()); diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/TimestampItemNormalizerTest.php b/core/modules/serialization/tests/src/Unit/Normalizer/TimestampItemNormalizerTest.php index 0db0ca71a5..47fead15d2 100644 --- a/core/modules/serialization/tests/src/Unit/Normalizer/TimestampItemNormalizerTest.php +++ b/core/modules/serialization/tests/src/Unit/Normalizer/TimestampItemNormalizerTest.php @@ -18,6 +18,8 @@ */ class TimestampItemNormalizerTest extends UnitTestCase { + use TypedDataTestTrait; + /** * @var \Drupal\serialization\Normalizer\TimestampItemNormalizer */ @@ -77,12 +79,18 @@ public function testNormalize() { $timestamp_item->getIterator() ->willReturn(new \ArrayIterator(['value' => 1478422920])); - $timestamp_item->getExposedProperties() - ->willReturn(['value' => 1478422920]) + $exposed_property = $this->getTypedDataProperty(); + $timestamp_item->getProperties(TRUE) + ->willReturn(['value' => $exposed_property]) + ->shouldBeCalled(); + + $serializer_prophecy = $this->prophesize(Serializer::class); + + $serializer_prophecy->normalize($exposed_property, NULL, []) + ->willReturn(1478422920) ->shouldBeCalled(); - $serializer = new Serializer(); - $this->normalizer->setSerializer($serializer); + $this->normalizer->setSerializer($serializer_prophecy->reveal()); $normalized = $this->normalizer->normalize($timestamp_item->reveal()); $this->assertSame($expected, $normalized); diff --git a/core/modules/serialization/tests/src/Unit/Normalizer/TypedDataTestTrait.php b/core/modules/serialization/tests/src/Unit/Normalizer/TypedDataTestTrait.php new file mode 100644 index 0000000000..257bf4ca38 --- /dev/null +++ b/core/modules/serialization/tests/src/Unit/Normalizer/TypedDataTestTrait.php @@ -0,0 +1,36 @@ +prophesize(DataDefinitionInterface::class); + $exposed_definition->isExposed() + ->willReturn($exposed) + ->shouldBeCalled(); + $exposed_definition = $exposed_definition->reveal(); + + $exposed_property = $this->prophesize(TypedDataInterface::class); + $exposed_property->getDataDefinition() + ->willReturn($exposed_definition) + ->shouldBeCalled(); + return $exposed_property->reveal(); + } + +}