Commit cf2b9be6 authored by catch's avatar catch

Issue #2820743 by damiankloip, dawehner: FieldNormalizers are very...

Issue #2820743 by damiankloip, dawehner: FieldNormalizers are very unforgiving, impossible to debug error response given
parent 2e4a1c7a
......@@ -3,19 +3,19 @@
namespace Drupal\hal\Normalizer;
use Drupal\Component\Utility\NestedArray;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Drupal\serialization\Normalizer\FieldNormalizer as SerializationFieldNormalizer;
/**
* Converts the Drupal field structure to HAL array structure.
*/
class FieldNormalizer extends NormalizerBase {
class FieldNormalizer extends SerializationFieldNormalizer {
/**
* The interface or class that this Normalizer supports.
* The formats that the Normalizer can handle.
*
* @var string
* @var array
*/
protected $supportedInterfaceOrClass = 'Drupal\Core\Field\FieldItemListInterface';
protected $format = ['hal_json'];
/**
* {@inheritdoc}
......@@ -51,33 +51,6 @@ public function normalize($field, $format = NULL, array $context = array()) {
return $normalized;
}
/**
* {@inheritdoc}
*/
public function denormalize($data, $class, $format = NULL, array $context = array()) {
if (!isset($context['target_instance'])) {
throw new InvalidArgumentException('$context[\'target_instance\'] must be set to denormalize with the FieldNormalizer');
}
if ($context['target_instance']->getParent() == NULL) {
throw new InvalidArgumentException('The field passed in via $context[\'target_instance\'] must have a parent set.');
}
$items = $context['target_instance'];
$item_class = $items->getItemDefinition()->getClass();
foreach ($data as $item_data) {
// Create a new item and pass it as the target for the unserialization of
// $item_data. Note: if $item_data is about a different language than the
// default, FieldItemNormalizer::denormalize() will dismiss this item and
// create a new one for the right language.
$context['target_instance'] = $items->appendItem();
$this->serializer->denormalize($item_data, $item_class, $format, $context);
}
return $items;
}
/**
* Helper function to normalize field items.
*
......
......@@ -4,6 +4,7 @@
use Drupal\Core\Field\FieldItemListInterface;
use Symfony\Component\Serializer\Exception\InvalidArgumentException;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
/**
......@@ -30,9 +31,18 @@ public function denormalize($data, $class, $format = NULL, array $context = arra
throw new InvalidArgumentException('$context[\'target_instance\'] must be set to denormalize with the FieldNormalizer');
}
if ($context['target_instance']->getParent() == NULL) {
throw new InvalidArgumentException('The field passed in via $context[\'target_instance\'] must have a parent set.');
}
/** @var FieldItemListInterface $items */
$items = $context['target_instance'];
$item_class = $items->getItemDefinition()->getClass();
if (!is_array($data)) {
throw new UnexpectedValueException(sprintf('Field values for "%s" must use an array structure', $items->getName()));
}
foreach ($data as $item_data) {
// Create a new item and pass it as the target for the unserialization of
// $item_data. All items in field should have removed before this method
......
......@@ -5,6 +5,7 @@
use Drupal\entity_test\Entity\EntityTestMulRev;
use Drupal\field\Entity\FieldConfig;
use Drupal\field\Entity\FieldStorageConfig;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
/**
* Test field level normalization process.
......@@ -117,4 +118,18 @@ public function testFieldNormalizeDenormalize() {
$this->assertEquals($denormalized_without_all_fields->field_test_text_default[0]->getValue(), $this->entity->field_test_text_default[0]->getValue(), 'Text field item with default denormalized.');
}
/**
* Tests denormalizing using a scalar field value.
*/
public function testFieldDenormalizeWithScalarValue() {
$this->setExpectedException(UnexpectedValueException::class, 'Field values for "uuid" must use an array structure');
$normalized = $this->serializer->normalize($this->entity, 'json');
// Change the UUID value to use the UUID directly. No array structure.
$normalized['uuid'] = $normalized['uuid'][0]['value'];
$this->serializer->denormalize($normalized, $this->entityClass, 'json');
}
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment