Skip to content

Commit 7fa114c

Browse files
committed
[Serializer] Added a ConstraintViolationListNormalizer
1 parent 2dfd136 commit 7fa114c

File tree

4 files changed

+124
-0
lines changed

4 files changed

+124
-0
lines changed

src/Symfony/Bundle/FrameworkBundle/DependencyInjection/FrameworkExtension.php

+8
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333
use Symfony\Component\Serializer\Encoder\YamlEncoder;
3434
use Symfony\Component\Serializer\Encoder\CsvEncoder;
3535
use Symfony\Component\Serializer\Mapping\Factory\CacheClassMetadataFactory;
36+
use Symfony\Component\Serializer\Normalizer\ConstraintViolationListNormalizer;
3637
use Symfony\Component\Serializer\Normalizer\DataUriNormalizer;
3738
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
3839
use Symfony\Component\Serializer\Normalizer\JsonSerializableNormalizer;
@@ -1202,6 +1203,13 @@ private function registerSerializerConfiguration(array $config, ContainerBuilder
12021203
$definition->addTag('serializer.normalizer', array('priority' => -900));
12031204
}
12041205

1206+
if (class_exists('Symfony\Component\Serializer\Normalizer\ConstraintViolationListNormalizer')) {
1207+
// Run before serializer.normalizer.object
1208+
$definition = $container->register('serializer.normalizer.constraint_violation_list_normalizer', ConstraintViolationListNormalizer::class);
1209+
$definition->setPublic(false);
1210+
$definition->addTag('serializer.normalizer', array('priority' => -900));
1211+
}
1212+
12051213
if (class_exists(YamlEncoder::class) && defined('Symfony\Component\Yaml\Yaml::DUMP_OBJECT')) {
12061214
$definition = $container->register('serializer.encoder.yaml', YamlEncoder::class);
12071215
$definition->setPublic(false);

src/Symfony/Component/Serializer/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ CHANGELOG
55
-----
66

77
* added `SerializerPass`
8+
* added `ConstraintViolationListNormalizer`
89

910
3.1.0
1011
-----
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Normalizer;
13+
14+
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
15+
use Symfony\Component\Validator\ConstraintViolationListInterface;
16+
17+
/**
18+
* A normalizer that uses an objects own JsonSerializable implementation.
19+
*
20+
* @author Grégoire Pineau <lyrixx@lyrixx.info>
21+
* @author Kévin Dunglas <dunglas@gmail.com>
22+
*/
23+
class ConstraintViolationListNormalizer implements NormalizerInterface
24+
{
25+
public function normalize($violationsList, $format = null, array $context = [])
26+
{
27+
$violations = [];
28+
$messages = [];
29+
30+
foreach ($violationsList as $violation) {
31+
$propertyPath = $violation->getPropertyPath();
32+
33+
$violations[] = [
34+
'propertyPath' => $propertyPath,
35+
'message' => $violation->getMessage(),
36+
];
37+
38+
$prefix = $propertyPath ? sprintf('%s: ', $propertyPath) : '';
39+
40+
$messages [] = $prefix.$violation->getMessage();
41+
}
42+
43+
return [
44+
'title' => 'An error occurred',
45+
'detail' => $messages ? implode("\n", $messages) : (string) $violationsList,
46+
'violations' => $violations,
47+
];
48+
}
49+
50+
public function supportsNormalization($data, $format = null)
51+
{
52+
return $data instanceof ConstraintViolationListInterface;
53+
}
54+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Serializer\Tests\Normalizer;
13+
14+
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Serializer\Normalizer\ConstraintViolationListNormalizer;
16+
use Symfony\Component\Validator\ConstraintViolation;
17+
use Symfony\Component\Validator\ConstraintViolationList;
18+
19+
/**
20+
* @author Grégoire Pineau <lyrixx@lyrixx.info>
21+
* @author Kévin Dunglas <dunglas@gmail.com>
22+
*/
23+
class ConstraintViolationNormalizerTest extends TestCase
24+
{
25+
private $normalizer;
26+
27+
protected function setUp()
28+
{
29+
$this->normalizer = new ConstraintViolationListNormalizer();
30+
}
31+
32+
public function testSupportsNormalization()
33+
{
34+
$this->assertTrue($this->normalizer->supportsNormalization(new ConstraintViolationList()));
35+
$this->assertFalse($this->normalizer->supportsNormalization(new \stdClass()));
36+
}
37+
38+
public function testNormalize()
39+
{
40+
$list = new ConstraintViolationList([
41+
new ConstraintViolation('a', 'b', [], 'c', 'd', 'e'),
42+
new ConstraintViolation('1', '2', [], '3', '4', '5'),
43+
]);
44+
45+
$expected = [
46+
'title' => 'An error occurred',
47+
'detail' => "d: a\n4: 1",
48+
'violations' => [
49+
[
50+
'propertyPath' => 'd',
51+
'message' => 'a',
52+
],
53+
[
54+
'propertyPath' => '4',
55+
'message' => '1',
56+
],
57+
],
58+
];
59+
$this->assertEquals($expected, $this->normalizer->normalize($list));
60+
}
61+
}

0 commit comments

Comments
 (0)