[Serializer] Added a ConstraintViolationListNormalizer

This commit is contained in:
Grégoire Pineau 2017-03-24 17:17:33 +01:00
parent bbeca51171
commit 2a35d09f53
6 changed files with 137 additions and 1 deletions

View File

@ -73,6 +73,7 @@ use Symfony\Component\Serializer\Encoder\EncoderInterface;
use Symfony\Component\Serializer\Mapping\ClassDiscriminatorFromClassMetadata;
use Symfony\Component\Serializer\Mapping\Factory\CacheClassMetadataFactory;
use Symfony\Component\Serializer\Normalizer\DateIntervalNormalizer;
use Symfony\Component\Serializer\Normalizer\ConstraintViolationListNormalizer;
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
use Symfony\Component\Stopwatch\Stopwatch;
@ -1227,6 +1228,10 @@ class FrameworkExtension extends Extension
$container->removeDefinition('serializer.normalizer.dateinterval');
}
if (!class_exists(ConstraintViolationListNormalizer::class)) {
$container->removeDefinition('serializer.normalizer.constraint_violation_list');
}
if (!class_exists(ClassDiscriminatorFromClassMetadata::class)) {
$container->removeAlias('Symfony\Component\Serializer\Mapping\ClassDiscriminatorResolverInterface');
$container->removeDefinition('serializer.mapping.class_discriminator_resolver');

View File

@ -31,6 +31,11 @@
<service id="Symfony\Component\Serializer\Mapping\ClassDiscriminatorResolverInterface" alias="serializer.mapping.class_discriminator_resolver" />
<!-- Normalizer -->
<service id="serializer.normalizer.constraint_violation_list" class="Symfony\Component\Serializer\Normalizer\ConstraintViolationListNormalizer">
<!-- Run before serializer.normalizer.object -->
<tag name="serializer.normalizer" priority="-915" />
</service>
<service id="serializer.normalizer.dateinterval" class="Symfony\Component\Serializer\Normalizer\DateIntervalNormalizer">
<!-- Run before serializer.normalizer.object -->
<tag name="serializer.normalizer" priority="-915" />

View File

@ -13,6 +13,7 @@ CHANGELOG
maximum depth is reached
* added optional `int[] $ignoredNodeTypes` argument to `XmlEncoder::__construct`. XML decoding now
ignores comment node types by default.
* added `ConstraintViolationListNormalizer`
4.0.0
-----

View File

@ -0,0 +1,59 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Serializer\Normalizer;
use Symfony\Component\Validator\ConstraintViolationListInterface;
/**
* A normalizer that normalizes a ConstraintViolationListInterface instance.
*
* This Normalizer implements RFC7807 {@link https://tools.ietf.org/html/rfc7807}.
*
*
* @author Grégoire Pineau <lyrixx@lyrixx.info>
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class ConstraintViolationListNormalizer implements NormalizerInterface
{
/**
* {@inheritdoc}
*/
public function normalize($object, $format = null, array $context = array())
{
$violations = array();
$messages = array();
foreach ($object as $violation) {
$violations[] = array(
'propertyPath' => $violation->getPropertyPath(),
'message' => $violation->getMessage(),
'code' => $violation->getCode(),
);
$propertyPath = $violation->getPropertyPath();
$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,
);
}
/**
* {@inheritdoc}
*/
public function supportsNormalization($data, $format = null)
{
return $data instanceof ConstraintViolationListInterface;
}
}

View File

@ -0,0 +1,65 @@
<?php
/*
* This file is part of the Symfony package.
*
* (c) Fabien Potencier <fabien@symfony.com>
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace Symfony\Component\Serializer\Tests\Normalizer;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Serializer\Normalizer\ConstraintViolationListNormalizer;
use Symfony\Component\Validator\ConstraintViolation;
use Symfony\Component\Validator\ConstraintViolationList;
/**
* @author Grégoire Pineau <lyrixx@lyrixx.info>
* @author Kévin Dunglas <dunglas@gmail.com>
*/
class ConstraintViolationListNormalizerTest extends TestCase
{
private $normalizer;
protected function setUp()
{
$this->normalizer = new ConstraintViolationListNormalizer();
}
public function testSupportsNormalization()
{
$this->assertTrue($this->normalizer->supportsNormalization(new ConstraintViolationList()));
$this->assertFalse($this->normalizer->supportsNormalization(new \stdClass()));
}
public function testNormalize()
{
$list = new ConstraintViolationList(array(
new ConstraintViolation('a', 'b', array(), 'c', 'd', 'e', null, 'f'),
new ConstraintViolation('1', '2', array(), '3', '4', '5', null, '6'),
));
$expected = array(
'title' => 'An error occurred',
'detail' => 'd: a
4: 1',
'violations' => array(
array(
'propertyPath' => 'd',
'message' => 'a',
'code' => 'f',
),
array(
'propertyPath' => '4',
'message' => '1',
'code' => '6',
),
),
);
$this->assertEquals($expected, $this->normalizer->normalize($list));
}
}

View File

@ -25,6 +25,7 @@
"symfony/http-foundation": "~3.4|~4.0",
"symfony/cache": "~3.4|~4.0",
"symfony/property-info": "~3.4|~4.0",
"symfony/validator": "~3.4|~4.0",
"doctrine/annotations": "~1.0",
"symfony/dependency-injection": "~3.4|~4.0",
"doctrine/cache": "~1.0",