diff --git a/core/modules/hal/lib/Drupal/hal/Normalizer/EntityNormalizer.php b/core/modules/hal/lib/Drupal/hal/Normalizer/EntityNormalizer.php index c85d7b9..3e7d6d4 100644 --- a/core/modules/hal/lib/Drupal/hal/Normalizer/EntityNormalizer.php +++ b/core/modules/hal/lib/Drupal/hal/Normalizer/EntityNormalizer.php @@ -90,18 +90,45 @@ public function normalize($entity, $format = NULL, array $context = array()) { * @throws \Symfony\Component\Serializer\Exception\UnexpectedValueException */ public function denormalize($data, $class, $format = NULL, array $context = array()) { + // Get type, necessary for determining which bundle to create. if (!isset($data['_links']['type'])) { throw new UnexpectedValueException('The type link relation must be specified.'); } $type_uri = $data['_links']['type']['href']; + // Get language. language_default() is used because otherwise the entity + // system cannot understand the langcode when working in the DrupalUnitTest + // environment and importing data without an explicit langcode. + $langcode = isset($data['langcode']) ? $data['langcode'][0]['value'] : language_default(); + + // Create the entity. if ($typed_data_ids = $this->linkManager->getTypedDataIds($type_uri)) { - $entity = entity_create($typed_data_ids['entity_type'], array('langcode' => 'en', 'type' => $typed_data_ids['bundle'])); + $entity = entity_create($typed_data_ids['entity_type'], array('langcode' => $langcode, 'type' => $typed_data_ids['bundle'])); } else { throw new UnexpectedValueException(sprintf('Type %s does not correspond to an entity on this site.', $type_uri)); } + // Get links and remove from data array. + $links = $data['_links']; + unset($data['_links']); + // Get embedded resources and remove from data array. + $embedded = array(); + if (isset($data['_embedded'])) { + $embedded = $data['_embedded']; + unset($data['_embedded']); + } + + // Iterate through remaining items in data array. These should all + // correspond to fields. + foreach ($data as $field_name => $field_data) { + // If the incoming value is an empty array, set the property to mark it + // for deletion. + if (empty($field_data) && is_array($field_data)) { + $entity->{$field_name} = array(); + } + } + return $entity; } diff --git a/core/modules/hal/lib/Drupal/hal/Tests/DenormalizeTest.php b/core/modules/hal/lib/Drupal/hal/Tests/DenormalizeTest.php index ae2b622..4108659 100644 --- a/core/modules/hal/lib/Drupal/hal/Tests/DenormalizeTest.php +++ b/core/modules/hal/lib/Drupal/hal/Tests/DenormalizeTest.php @@ -26,8 +26,6 @@ public static function getInfo() { * Tests that the type link relation in incoming data is handled correctly. */ public function testTypeHandling() { - $entity_class = 'Drupal\entity_test\Plugin\Core\Entity\EntityTest'; - // Valid type. $data_with_valid_type = array( '_links' => array( @@ -36,8 +34,8 @@ public function testTypeHandling() { ), ), ); - $denormalized = $this->container->get('serializer')->denormalize($data_with_valid_type, $entity_class, $this->format); - $this->assertEqual(get_class($denormalized), $entity_class, 'Request with valid type results in creation of correct bundle.'); + $denormalized = $this->container->get('serializer')->denormalize($data_with_valid_type, $this->entityClass, $this->format); + $this->assertEqual(get_class($denormalized), $this->entityClass, 'Request with valid type results in creation of correct bundle.'); // Invalid type. $data_with_invalid_type = array( @@ -48,7 +46,7 @@ public function testTypeHandling() { ), ); try { - $this->container->get('serializer')->denormalize($data_with_invalid_type, $entity_class, $this->format); + $this->container->get('serializer')->denormalize($data_with_invalid_type, $this->entityClass, $this->format); $this->fail('Exception thrown when type is invalid.'); } catch (UnexpectedValueException $e) { @@ -61,7 +59,7 @@ public function testTypeHandling() { ), ); try { - $this->container->get('serializer')->denormalize($data_with_no_type, $entity_class, $this->format); + $this->container->get('serializer')->denormalize($data_with_no_type, $this->entityClass, $this->format); $this->fail('Exception thrown when no type is provided.'); } catch (UnexpectedValueException $e) { @@ -69,4 +67,31 @@ public function testTypeHandling() { } } + /** + * Test that a field set to an empty array is different than an empty field. + */ + public function testMarkFieldForDeletion() { + $no_field_data = array( + '_links' => array( + 'type' => array( + 'href' => url('rest/types/entity_test/entity_test', array('absolute' => TRUE)), + ), + ), + ); + $no_field_denormalized = $this->container->get('serializer')->denormalize($no_field_data, $this->entityClass, $this->format); + $no_field_value = $no_field_denormalized->field_test_text->getValue(); + + $empty_field_data = array( + '_links' => array( + 'type' => array( + 'href' => url('rest/types/entity_test/entity_test', array('absolute' => TRUE)), + ), + ), + 'field_test_text' => array(), + ); + $empty_field_denormalized = $this->container->get('serializer')->denormalize($empty_field_data, $this->entityClass, $this->format); + $empty_field_value = $empty_field_denormalized->field_test_text->getValue(); + + $this->assertTrue(!empty($no_field_data) && empty($empty_field_value), 'A field set to an empty array in the data is structured differently than an empty field.'); + } } diff --git a/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php b/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php index b577f20..04d3118 100644 --- a/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php +++ b/core/modules/hal/lib/Drupal/hal/Tests/NormalizerTestBase.php @@ -32,6 +32,13 @@ protected $format = 'hal_json'; /** + * The class name of the test class. + * + * @var string + */ + protected $entityClass = 'Drupal\entity_test\Plugin\Core\Entity\EntityTest'; + + /** * Overrides \Drupal\simpletest\DrupalUnitTestBase::setup(). */ function setUp() {