[Serializer] Fix and improve constraintViolationListNormalizer's RFC7807 compliance

This commit is contained in:
Kévin Dunglas 2018-05-17 07:48:00 +02:00 committed by Fabien Potencier
parent 68eda49322
commit 3c789c610a
2 changed files with 31 additions and 14 deletions

View File

@ -32,21 +32,37 @@ class ConstraintViolationListNormalizer implements NormalizerInterface, Cacheabl
$violations = array();
$messages = array();
foreach ($object as $violation) {
$violations[] = array(
'propertyPath' => $violation->getPropertyPath(),
'message' => $violation->getMessage(),
'code' => $violation->getCode(),
);
$propertyPath = $violation->getPropertyPath();
$violationEntry = array(
'propertyPath' => $propertyPath,
'title' => $violation->getMessage(),
);
if (null !== $code = $violation->getCode()) {
$violationEntry['type'] = sprintf('urn:uuid:%s', $code);
}
$violations[] = $violationEntry;
$prefix = $propertyPath ? sprintf('%s: ', $propertyPath) : '';
$messages[] = $prefix.$violation->getMessage();
}
return array(
'title' => isset($context['title']) ? $context['title'] : 'An error occurred',
'detail' => $messages ? implode("\n", $messages) : '',
'violations' => $violations,
$result = array(
'type' => $context['type'] ?? 'https://symfony.com/errors/validation',
'title' => $context['title'] ?? 'Validation Failed',
);
if (isset($context['status'])) {
$result['status'] = $context['status'];
}
if ($messages) {
$result['detail'] = implode("\n", $messages);
}
if (isset($context['instance'])) {
$result['instance'] = $context['instance'];
}
return $result + array('violations' => $violations);
}
/**

View File

@ -43,19 +43,20 @@ class ConstraintViolationListNormalizerTest extends TestCase
));
$expected = array(
'title' => 'An error occurred',
'type' => 'https://symfony.com/errors/validation',
'title' => 'Validation Failed',
'detail' => 'd: a
4: 1',
'violations' => array(
array(
'propertyPath' => 'd',
'message' => 'a',
'code' => 'f',
'title' => 'a',
'type' => 'urn:uuid:f',
),
array(
'propertyPath' => '4',
'message' => '1',
'code' => '6',
'title' => '1',
'type' => 'urn:uuid:6',
),
),
);