Skip to content

Navigation Menu

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit a202da2

Browse filesBrowse files
committed
Add COLLECT_EXTRA_ATTRIBUTES_ERRORS and full deserialization path
1 parent c2af1fd commit a202da2
Copy full SHA for a202da2

18 files changed

+498
-103
lines changed

‎UPGRADE-6.2.md

Copy file name to clipboard
+65-79
Original file line numberDiff line numberDiff line change
@@ -1,113 +1,99 @@
1-
UPGRADE FROM 6.1 to 6.2
2-
=======================
1+
# UPGRADE FROM 6.1 to 6.2
32

4-
Config
5-
------
3+
## Config
64

7-
* Deprecate calling `NodeBuilder::setParent()` without any arguments
5+
- Deprecate calling `NodeBuilder::setParent()` without any arguments
86

9-
Console
10-
-------
7+
## Console
118

12-
* Deprecate calling `*Command::setApplication()`, `*FormatterStyle::setForeground/setBackground()`, `Helper::setHelpSet()`, `Input*::setDefault()`, `Question::setAutocompleterCallback/setValidator()`without any arguments
13-
* Change the signature of `OutputFormatterStyleInterface::setForeground/setBackground()` to `setForeground/setBackground(?string)`
14-
* Change the signature of `HelperInterface::setHelperSet()` to `setHelperSet(?HelperSet)`
9+
- Deprecate calling `*Command::setApplication()`, `*FormatterStyle::setForeground/setBackground()`, `Helper::setHelpSet()`, `Input*::setDefault()`, `Question::setAutocompleterCallback/setValidator()`without any arguments
10+
- Change the signature of `OutputFormatterStyleInterface::setForeground/setBackground()` to `setForeground/setBackground(?string)`
11+
- Change the signature of `HelperInterface::setHelperSet()` to `setHelperSet(?HelperSet)`
1512

16-
DependencyInjection
17-
-------------------
13+
## DependencyInjection
1814

19-
* Change the signature of `ContainerAwareInterface::setContainer()` to `setContainer(?ContainerInterface)`
20-
* Deprecate calling `ContainerAwareTrait::setContainer()` without arguments
21-
* Deprecate using numeric parameter names
15+
- Change the signature of `ContainerAwareInterface::setContainer()` to `setContainer(?ContainerInterface)`
16+
- Deprecate calling `ContainerAwareTrait::setContainer()` without arguments
17+
- Deprecate using numeric parameter names
2218

23-
Form
24-
----
19+
## Form
2520

26-
* Deprecate calling `Button/Form::setParent()`, `ButtonBuilder/FormConfigBuilder::setDataMapper()`, `TransformationFailedException::setInvalidMessage()` without arguments
27-
* Change the signature of `FormConfigBuilderInterface::setDataMapper()` to `setDataMapper(?DataMapperInterface)`
28-
* Change the signature of `FormInterface::setParent()` to `setParent(?self)`
21+
- Deprecate calling `Button/Form::setParent()`, `ButtonBuilder/FormConfigBuilder::setDataMapper()`, `TransformationFailedException::setInvalidMessage()` without arguments
22+
- Change the signature of `FormConfigBuilderInterface::setDataMapper()` to `setDataMapper(?DataMapperInterface)`
23+
- Change the signature of `FormInterface::setParent()` to `setParent(?self)`
2924

30-
FrameworkBundle
31-
---------------
25+
## FrameworkBundle
3226

33-
* Deprecate the `Symfony\Component\Serializer\Normalizer\ObjectNormalizer` and
34-
`Symfony\Component\Serializer\Normalizer\PropertyNormalizer` autowiring aliases, type-hint against
35-
`Symfony\Component\Serializer\Normalizer\NormalizerInterface` or implement `NormalizerAwareInterface` instead
36-
* Deprecate `AbstractController::renderForm()`, use `render()` instead
27+
- Deprecate the `Symfony\Component\Serializer\Normalizer\ObjectNormalizer` and
28+
`Symfony\Component\Serializer\Normalizer\PropertyNormalizer` autowiring aliases, type-hint against
29+
`Symfony\Component\Serializer\Normalizer\NormalizerInterface` or implement `NormalizerAwareInterface` instead
30+
- Deprecate `AbstractController::renderForm()`, use `render()` instead
3731

38-
HttpFoundation
39-
--------------
32+
## HttpFoundation
4033

41-
* Deprecate `Request::getContentType()`, use `Request::getContentTypeFormat()` instead
42-
* Deprecate calling `JsonResponse::setCallback()`, `Response::setExpires/setLastModified/setEtag()`, `MockArraySessionStorage/NativeSessionStorage::setMetadataBag()`, `NativeSessionStorage::setSaveHandler()` without arguments
34+
- Deprecate `Request::getContentType()`, use `Request::getContentTypeFormat()` instead
35+
- Deprecate calling `JsonResponse::setCallback()`, `Response::setExpires/setLastModified/setEtag()`, `MockArraySessionStorage/NativeSessionStorage::setMetadataBag()`, `NativeSessionStorage::setSaveHandler()` without arguments
4336

44-
HttpKernel
45-
----------
37+
## HttpKernel
4638

47-
* Deprecate `ArgumentValueResolverInterface`, use `ValueResolverInterface` instead
48-
* Deprecate calling `ConfigDataCollector::setKernel()`, `RouterListener::setCurrentRequest()` without arguments
39+
- Deprecate `ArgumentValueResolverInterface`, use `ValueResolverInterface` instead
40+
- Deprecate calling `ConfigDataCollector::setKernel()`, `RouterListener::setCurrentRequest()` without arguments
4941

50-
Ldap
51-
----
42+
## Ldap
5243

53-
* Deprecate `{username}` parameter use in favour of `{user_identifier}`
44+
- Deprecate `{username}` parameter use in favour of `{user_identifier}`
5445

55-
Mailer
56-
------
46+
## Mailer
5747

58-
* Deprecate the `OhMySMTP` transport, use `MailPace` instead
48+
- Deprecate the `OhMySMTP` transport, use `MailPace` instead
5949

60-
Mime
61-
----
50+
## Mime
6251

63-
* Deprecate calling `Message::setBody()` without arguments
52+
- Deprecate calling `Message::setBody()` without arguments
6453

65-
PropertyAccess
66-
--------------
54+
## PropertyAccess
6755

68-
* Deprecate calling `PropertyAccessorBuilder::setCacheItemPool()` without arguments
69-
* Implementing the `PropertyPathInterface` without implementing the `isNullSafe()` method is deprecated
56+
- Deprecate calling `PropertyAccessorBuilder::setCacheItemPool()` without arguments
57+
- Implementing the `PropertyPathInterface` without implementing the `isNullSafe()` method is deprecated
7058

71-
Messenger
72-
--------
59+
## Messenger
7360

74-
* Deprecate `MessageHandlerInterface` and `MessageSubscriberInterface`, use the `AsMessageHandler` attribute instead
61+
- Deprecate `MessageHandlerInterface` and `MessageSubscriberInterface`, use the `AsMessageHandler` attribute instead
7562

76-
Security
77-
--------
63+
## Security
7864

79-
* Add maximum username length enforcement of 4096 characters in `UserBadge` to
80-
prevent [session storage flooding](https://symfony.com/blog/cve-2016-4423-large-username-storage-in-session)
81-
* Deprecate the `Symfony\Component\Security\Core\Security` class and service, use `Symfony\Bundle\SecurityBundle\Security\Security` instead
82-
* Passing empty username or password parameter when using `JsonLoginAuthenticator` is not supported anymore
83-
* Add `$lifetime` parameter to `LoginLinkHandlerInterface::createLoginLink()`
84-
* Change the signature of `TokenStorageInterface::setToken()` to `setToken(?TokenInterface $token)`
85-
* Deprecate calling `TokenStorage::setToken()` or `UsageTrackingTokenStorage::setToken()` without arguments
65+
- Add maximum username length enforcement of 4096 characters in `UserBadge` to
66+
prevent [session storage flooding](https://symfony.com/blog/cve-2016-4423-large-username-storage-in-session)
8667

87-
Serializer
88-
----------
68+
## Serializer
8969

90-
* Deprecate calling `AttributeMetadata::setSerializedName()`, `ClassMetadata::setClassDiscriminatorMapping()` without arguments
91-
* Change the signature of `AttributeMetadataInterface::setSerializedName()` to `setSerializedName(?string)`
92-
* Change the signature of `ClassMetadataInterface::setClassDiscriminatorMapping()` to `setClassDiscriminatorMapping(?ClassDiscriminatorMapping)`
70+
- Deprecate the `Symfony\Component\Security\Core\Security` class and service, use `Symfony\Bundle\SecurityBundle\Security\Security` instead
71+
- Passing empty username or password parameter when using `JsonLoginAuthenticator` is not supported anymore
72+
- Add `$lifetime` parameter to `LoginLinkHandlerInterface::createLoginLink()`
73+
- Change the signature of `TokenStorageInterface::setToken()` to `setToken(?TokenInterface $token)`
74+
- Deprecate calling `TokenStorage::setToken()` or `UsageTrackingTokenStorage::setToken()` without arguments
9375

94-
Validator
95-
---------
76+
## Serializer
9677

97-
* Deprecate the `loose` e-mail validation mode, use `html5` instead
78+
- Deprecate calling `AttributeMetadata::setSerializedName()`, `ClassMetadata::setClassDiscriminatorMapping()` without arguments
79+
- Change the signature of `AttributeMetadataInterface::setSerializedName()` to `setSerializedName(?string)`
80+
- Change the signature of `ClassMetadataInterface::setClassDiscriminatorMapping()` to `setClassDiscriminatorMapping(?ClassDiscriminatorMapping)`
81+
- Deprecate `PartialDenormalizationException::getErrors()`, call `getNotNormalizableValueErrors()` instead
9882

99-
VarDumper
100-
---------
83+
## Validator
10184

102-
* Deprecate calling `VarDumper::setHandler()` without arguments
85+
- Deprecate the `loose` e-mail validation mode, use `html5` instead
10386

104-
Workflow
105-
--------
87+
## VarDumper
10688

107-
* The `Registry` is marked as internal and should not be used directly. use a tagged locator instead
108-
```
109-
tagged_locator('workflow', 'name')
110-
```
111-
* The first argument of `WorkflowDumpCommand` should be a `ServiceLocator` of
112-
all workflows indexed by names
113-
* Deprecate calling `Definition::setInitialPlaces()` without arguments
89+
- Deprecate calling `VarDumper::setHandler()` without arguments
90+
91+
## Workflow
92+
93+
- The `Registry` is marked as internal and should not be used directly. use a tagged locator instead
94+
```
95+
tagged_locator('workflow', 'name')
96+
```
97+
- The first argument of `WorkflowDumpCommand` should be a `ServiceLocator` of
98+
all workflows indexed by names
99+
- Deprecate calling `Definition::setInitialPlaces()` without arguments

‎src/Symfony/Component/Console/Helper/Table.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Console/Helper/Table.php
+1-1
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,7 @@ public function setHeaders(array $headers): static
192192
/**
193193
* @return $this
194194
*/
195-
public function setRows(array $rows)
195+
public function setRows(array $rows): static
196196
{
197197
$this->rows = [];
198198

‎src/Symfony/Component/PropertyAccess/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/PropertyAccess/CHANGELOG.md
+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ CHANGELOG
66

77
* Deprecate calling `PropertyAccessorBuilder::setCacheItemPool()` without arguments
88
* Added method `isNullSafe()` to `PropertyPathInterface`
9+
* Add `Symfony\Component\PropertyAccess\PropertyPath::append()`
910

1011
6.0
1112
---

‎src/Symfony/Component/PropertyAccess/PropertyPath.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/PropertyAccess/PropertyPath.php
+25
Original file line numberDiff line numberDiff line change
@@ -203,4 +203,29 @@ public function isNullSafe(int $index): bool
203203

204204
return $this->isNullSafe[$index];
205205
}
206+
207+
/**
208+
* Utility method for dealing with property paths.
209+
* For more extensive functionality, use instances of this class.
210+
*
211+
* Appends a path to a given property path.
212+
*
213+
* If the base path is empty, the appended path will be returned unchanged.
214+
* If the base path is not empty, and the appended path starts with a
215+
* squared opening bracket ("["), the concatenation of the two paths is
216+
* returned. Otherwise, the concatenation of the two paths is returned,
217+
* separated by a dot (".").
218+
*/
219+
public static function append(string $basePath, string $subPath): string
220+
{
221+
if ('' !== $subPath) {
222+
if ('[' === $subPath[0]) {
223+
return $basePath.$subPath;
224+
}
225+
226+
return '' !== $basePath ? $basePath.'.'.$subPath : $subPath;
227+
}
228+
229+
return $basePath;
230+
}
206231
}

‎src/Symfony/Component/PropertyAccess/Tests/PropertyPathTest.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/PropertyAccess/Tests/PropertyPathTest.php
+20
Original file line numberDiff line numberDiff line change
@@ -170,4 +170,24 @@ public function testIsIndexDoesNotAcceptNegativeIndices()
170170

171171
$propertyPath->isIndex(-1);
172172
}
173+
174+
/**
175+
* @dataProvider provideAppendPaths
176+
*/
177+
public function testAppend($basePath, $subPath, $expectedPath, $message)
178+
{
179+
$this->assertSame($expectedPath, PropertyPath::append($basePath, $subPath), $message);
180+
}
181+
182+
public function provideAppendPaths()
183+
{
184+
return [
185+
['foo', '', 'foo', 'It returns the basePath if subPath is empty'],
186+
['', 'bar', 'bar', 'It returns the subPath if basePath is empty'],
187+
['foo', 'bar', 'foo.bar', 'It append the subPath to the basePath'],
188+
['foo', '[bar]', 'foo[bar]', 'It does not include the dot separator if subPath uses the array notation'],
189+
['0', 'bar', '0.bar', 'Leading zeros are kept.'],
190+
['0', 1, '0.1', 'Numeric subpaths do not cause PHP 7.4 errors.'],
191+
];
192+
}
173193
}

‎src/Symfony/Component/Serializer/CHANGELOG.md

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/CHANGELOG.md
+2
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@ CHANGELOG
1111
* Change the signature of `AttributeMetadataInterface::setSerializedName()` to `setSerializedName(?string)`
1212
* Change the signature of `ClassMetadataInterface::setClassDiscriminatorMapping()` to `setClassDiscriminatorMapping(?ClassDiscriminatorMapping)`
1313
* Add option YamlEncoder::YAML_INDENTATION to YamlEncoder constructor options to configure additional indentation for each level of nesting. This allows configuring indentation in the service configuration.
14+
* Add `COLLECT_EXTRA_ATTRIBUTES_ERRORS` option to `Serializer` to collect errors from nested denormalizations
15+
* Deprecate `PartialDenormalizationException::getErrors()`, call `getNotNormalizableValueErrors()` instead
1416

1517
6.1
1618
---

‎src/Symfony/Component/Serializer/Context/SerializerContextBuilder.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Context/SerializerContextBuilder.php
+6
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111

1212
namespace Symfony\Component\Serializer\Context;
1313

14+
use Symfony\Component\Serializer\Normalizer\AbstractNormalizer;
1415
use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
1516
use Symfony\Component\Serializer\Serializer;
1617

@@ -36,4 +37,9 @@ public function withCollectDenormalizationErrors(?bool $collectDenormalizationEr
3637
{
3738
return $this->with(DenormalizerInterface::COLLECT_DENORMALIZATION_ERRORS, $collectDenormalizationErrors);
3839
}
40+
41+
public function withCollectExtraAttributesErrors(?bool $collectExtraAttributesErrors): static
42+
{
43+
return $this->with(DenormalizerInterface::COLLECT_EXTRA_ATTRIBUTES_ERRORS, $collectExtraAttributesErrors);
44+
}
3945
}

‎src/Symfony/Component/Serializer/Exception/PartialDenormalizationException.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Exception/PartialDenormalizationException.php
+28-4
Original file line numberDiff line numberDiff line change
@@ -17,21 +17,45 @@
1717
class PartialDenormalizationException extends UnexpectedValueException
1818
{
1919
private $data;
20-
private $errors;
20+
/**
21+
* @var NotNormalizableValueException[]
22+
*/
23+
private array $notNormalizableErrors;
24+
private ?ExtraAttributesException $extraAttributesError = null;
2125

22-
public function __construct($data, array $errors)
26+
public function __construct($data, array $notNormalizableErrors, array $extraAttributesErrors = [])
2327
{
2428
$this->data = $data;
25-
$this->errors = $errors;
29+
$this->notNormalizableErrors = $notNormalizableErrors;
30+
$extraAttributes = [];
31+
foreach ($extraAttributesErrors as $error) {
32+
\array_push($extraAttributes, ...$error->getExtraAttributes());
33+
}
34+
if (\count($extraAttributes) > 0) {
35+
$this->extraAttributesError = new ExtraAttributesException($extraAttributes);
36+
}
2637
}
2738

2839
public function getData()
2940
{
3041
return $this->data;
3142
}
3243

44+
/**
45+
* @deprecated Use getNotNormalizableValueErrors() instead.
46+
*/
3347
public function getErrors(): array
3448
{
35-
return $this->errors;
49+
return $this->getNotNormalizableValueErrors();
50+
}
51+
52+
public function getNotNormalizableValueErrors(): array
53+
{
54+
return $this->notNormalizableErrors;
55+
}
56+
57+
public function getExtraAttributesError(): ?ExtraAttributesException
58+
{
59+
return $this->extraAttributesError;
3660
}
3761
}

‎src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php

Copy file name to clipboardExpand all lines: src/Symfony/Component/Serializer/Normalizer/AbstractNormalizer.php
+2-1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
use Symfony\Component\Serializer\NameConverter\NameConverterInterface;
2323
use Symfony\Component\Serializer\SerializerAwareInterface;
2424
use Symfony\Component\Serializer\SerializerAwareTrait;
25+
use Symfony\Component\Serializer\Util\PropertyPath;
2526

2627
/**
2728
* Normalizer implementation.
@@ -505,7 +506,7 @@ protected function getAttributeNormalizationContext(object $object, string $attr
505506
*/
506507
protected function getAttributeDenormalizationContext(string $class, string $attribute, array $context): array
507508
{
508-
$context['deserialization_path'] = ($context['deserialization_path'] ?? false) ? $context['deserialization_path'].'.'.$attribute : $attribute;
509+
$context['deserialization_path'] = PropertyPath::append($context['deserialization_path'] ?? '', $attribute);
509510

510511
if (null === $metadata = $this->getAttributeMetadata($class, $attribute)) {
511512
return $context;

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.