diff --git a/core/lib/Drupal/Core/TypedData/TypedDataManager.php b/core/lib/Drupal/Core/TypedData/TypedDataManager.php index 273066d411..228722fdf0 100644 --- a/core/lib/Drupal/Core/TypedData/TypedDataManager.php +++ b/core/lib/Drupal/Core/TypedData/TypedDataManager.php @@ -169,10 +169,6 @@ public function getPropertyInstance(TypedDataInterface $object, $property_name, $parts[] = json_encode($settings); } // Property path for the requested data object. - // the original code is: - // code$parts[] = $object->getPropertyPath() . '.' . (is_numeric($property_name) ? 0 : $property_name); - // When creating a list item , use 0 in the key as all items look the same. - // But wen Map data use setPropertyDefinition, We may pass an array that has numerical key with different type of value $parts[] = $object->getPropertyPath() . '.' . $property_name; $key = implode(':', $parts); diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestMapItemNormalizerTest.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestMapItemNormalizerTest.php new file mode 100644 index 0000000000..018706ee61 --- /dev/null +++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityTest/EntityTestMapItemNormalizerTest.php @@ -0,0 +1,95 @@ + 'value', + 'key2' => 'no, val you', + 'nested' => [ + 'bird' => 'robin', + 'doll' => 'Russian', + ], + ]; + + + /** + * {@inheritdoc} + */ + protected static $mimeType = 'application/json'; + + /** + * {@inheritdoc} + */ + protected function getExpectedNormalizedEntity() { + $expected = parent::getExpectedNormalizedEntity(); + // The 'non_exposed_value' property in test field type will not return in + // normalization because setExposed(TRUE) was not called for this property. + // @see \Drupal\entity_test\Plugin\Field\FieldType\ExposedPropertyTestFieldItem::propertyDefinitions + $expected['field_map'] = [ + [ + 'freeform' => static::$mapValue, + ], + ]; + return $expected; + } + + /** + * {@inheritdoc} + */ + protected function createEntity() { + if (!FieldStorageConfig::loadByName('entity_test', 'field_map')) { + FieldStorageConfig::create([ + 'entity_type' => 'entity_test', + 'field_name' => 'field_map', + 'type' => 'map_test', + 'cardinality' => 1, + 'translatable' => FALSE, + ])->save(); + FieldConfig::create([ + 'entity_type' => 'entity_test', + 'field_name' => 'field_map', + 'bundle' => 'entity_test', + 'label' => 'Test field with map property', + ])->save(); + } + + $entity = parent::createEntity(); + $entity->field_map = [ + 'freeform' => static::$mapValue, + ]; + $entity->save(); + return $entity; + } + + /** + * {@inheritdoc} + */ + protected function getNormalizedPostEntity() { + return parent::getNormalizedPostEntity() + [ + 'field_map' => [ + [ + 'freeform' => static::$mapValue, + ], + ], + ]; + } + +} diff --git a/core/modules/serialization/serialization.services.yml b/core/modules/serialization/serialization.services.yml index 1e28a28b2c..8ad0206c35 100644 --- a/core/modules/serialization/serialization.services.yml +++ b/core/modules/serialization/serialization.services.yml @@ -74,7 +74,21 @@ services: serializer.normalizer.map: class: Drupal\serialization\Normalizer\MapNormalizer tags: - - { name: normalizer, priority: 25} + # This normalizer must be higher than serializer.normalizer.complex_data so + # that serializer.normalizer.complex_data is not used for Map objects that + # do not provide property definitions. While giving this normalizer a + # priority of 1 would work when considering only core's normalizers it would + # not allow for any other custom normalizers to given priority between + # serializer.normalizer.complex_data and this normalizer. Giving this + # normalizer an especially high priority allows normalizers with range of + # priorities for other classes that do not provide property definitions. + # Giving this normalizer an especially + # high priority will NOT cause it to be used for most classes that extend + # Map, such any class that extends \Drupal\Core\Field\FieldItemBase, + # because those objects will have property definitions. + # + # @see \Drupal\serialization\Normalizer\MapNormalizer::supportsNormalization + - { name: normalizer, priority: 20} serializer.encoder.json: class: Drupal\serialization\Encoder\JsonEncoder tags: diff --git a/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/MapItem.php b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/MapItem.php new file mode 100644 index 0000000000..0cc51cc807 --- /dev/null +++ b/core/modules/system/tests/modules/entity_test/src/Plugin/Field/FieldType/MapItem.php @@ -0,0 +1,45 @@ + MapDataDefinition::create()->setLabel(t('Freeform')), + ]; + } + + /** + * {@inheritdoc} + */ + public static function schema(FieldStorageDefinitionInterface $field_definition) { + return [ + 'columns' => [ + 'freeform' => [ + 'description' => 'Serialized array of stuff.', + 'type' => 'blob', + 'size' => 'big', + 'serialize' => TRUE, + ], + ], + ]; + } + +}