Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 04e22ec

Browse files
add context to force snake_case
1 parent bc2d994 commit 04e22ec

File tree

4 files changed

+65
-3
lines changed

4 files changed

+65
-3
lines changed

src/Symfony/Component/HttpKernel/Controller/ArgumentResolver/RequestPayloadValueResolver.php

+3
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
use Symfony\Component\HttpKernel\KernelEvents;
2525
use Symfony\Component\Serializer\Exception\NotEncodableValueException;
2626
use Symfony\Component\Serializer\Exception\PartialDenormalizationException;
27+
use Symfony\Component\Serializer\Exception\UnexpectedPropertyException;
2728
use Symfony\Component\Serializer\Exception\UnsupportedFormatException;
2829
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
2930
use Symfony\Component\Serializer\SerializerInterface;
@@ -197,6 +198,8 @@ private function mapRequestPayload(Request $request, string $type, MapRequestPay
197198
throw new UnsupportedMediaTypeHttpException(sprintf('Unsupported format: "%s".', $format), $e);
198199
} catch (NotEncodableValueException $e) {
199200
throw new BadRequestHttpException(sprintf('Request payload contains invalid "%s" data.', $format), $e);
201+
} catch (UnexpectedPropertyException $e) {
202+
throw new BadRequestHttpException(sprintf('Request payload contains invalid "%s" property.', $e->property), $e);
200203
}
201204
}
202205
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <[email protected]>
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\Exception;
13+
14+
/**
15+
* UnexpectedPropertyException.
16+
*
17+
* @author Aurélien Pillevesse <[email protected]>
18+
*/
19+
class UnexpectedPropertyException extends \UnexpectedValueException implements ExceptionInterface
20+
{
21+
public function __construct(
22+
public readonly string $property,
23+
?\Throwable $previous = null,
24+
) {
25+
$msg = sprintf('Property is not allowed ("%s" is unknown).', $this->property);
26+
27+
parent::__construct($msg, 0, $previous);
28+
}
29+
}

src/Symfony/Component/Serializer/NameConverter/CamelCaseToSnakeCaseNameConverter.php

+15-3
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,21 @@
1111

1212
namespace Symfony\Component\Serializer\NameConverter;
1313

14+
use Symfony\Component\Serializer\Exception\UnexpectedPropertyException;
15+
1416
/**
1517
* CamelCase to Underscore name converter.
1618
*
1719
* @author Kévin Dunglas <[email protected]>
20+
* @author Aurélien Pillevesse <[email protected]>
1821
*/
19-
class CamelCaseToSnakeCaseNameConverter implements NameConverterInterface
22+
class CamelCaseToSnakeCaseNameConverter implements AdvancedNameConverterInterface
2023
{
24+
/**
25+
* Require all properties to be written in snake_case.
26+
*/
27+
public const REQUIRE_SNAKE_CASE_PROPERTIES = 'require_snake_case_properties';
28+
2129
/**
2230
* @param array|null $attributes The list of attributes to rename or null for all attributes
2331
* @param bool $lowerCamelCase Use lowerCamelCase style
@@ -28,7 +36,7 @@ public function __construct(
2836
) {
2937
}
3038

31-
public function normalize(string $propertyName): string
39+
public function normalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string
3240
{
3341
if (null === $this->attributes || \in_array($propertyName, $this->attributes, true)) {
3442
return strtolower(preg_replace('/[A-Z]/', '_\\0', lcfirst($propertyName)));
@@ -37,8 +45,12 @@ public function normalize(string $propertyName): string
3745
return $propertyName;
3846
}
3947

40-
public function denormalize(string $propertyName): string
48+
public function denormalize(string $propertyName, ?string $class = null, ?string $format = null, array $context = []): string
4149
{
50+
if (($context[self::REQUIRE_SNAKE_CASE_PROPERTIES] ?? false) && $propertyName !== $this->normalize($propertyName, $class, $format, $context)) {
51+
throw new UnexpectedPropertyException($propertyName);
52+
}
53+
4254
$camelCasedName = preg_replace_callback('/(^|_|\.)+(.)/', fn ($match) => ('.' === $match[1] ? '_' : '').strtoupper($match[2]), $propertyName);
4355

4456
if ($this->lowerCamelCase) {

src/Symfony/Component/Serializer/Tests/NameConverter/CamelCaseToSnakeCaseNameConverterTest.php

+18
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,13 @@
1212
namespace Symfony\Component\Serializer\Tests\NameConverter;
1313

1414
use PHPUnit\Framework\TestCase;
15+
use Symfony\Component\Serializer\Exception\UnexpectedPropertyException;
1516
use Symfony\Component\Serializer\NameConverter\CamelCaseToSnakeCaseNameConverter;
1617
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
1718

1819
/**
1920
* @author Kévin Dunglas <[email protected]>
21+
* @author Aurélien Pillevesse <[email protected]>
2022
*/
2123
class CamelCaseToSnakeCaseNameConverterTest extends TestCase
2224
{
@@ -55,4 +57,20 @@ public static function attributeProvider()
5557
['this_is_a_test', 'ThisIsATest', false],
5658
];
5759
}
60+
61+
public function testDenormalizeWithContext()
62+
{
63+
$nameConverter = new CamelCaseToSnakeCaseNameConverter(null, true);
64+
$denormalizedValue = $nameConverter->denormalize('last_name', context: [CamelCaseToSnakeCaseNameConverter::REQUIRE_SNAKE_CASE_PROPERTIES]);
65+
66+
$this->assertSame($denormalizedValue, 'lastName');
67+
}
68+
69+
public function testErrorDenormalizeWithContext()
70+
{
71+
$nameConverter = new CamelCaseToSnakeCaseNameConverter(null, true);
72+
73+
$this->expectException(UnexpectedPropertyException::class);
74+
$nameConverter->denormalize('lastName', context: [CamelCaseToSnakeCaseNameConverter::REQUIRE_SNAKE_CASE_PROPERTIES => true]);
75+
}
5876
}

0 commit comments

Comments
 (0)