Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

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

Sign up
Appearance settings

Commitbd4277c

Browse files
boennernicolas-grekas
authored andcommitted
[Serializer] Flatten nested attributes
1 parentc63bd7e commitbd4277c

File tree

25 files changed

+616
-34
lines changed

25 files changed

+616
-34
lines changed

‎src/Symfony/Component/Serializer/Annotation/SerializedName.php‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ final class SerializedName
2727
{
2828
publicfunction__construct(privatestring$serializedName)
2929
{
30-
if (empty($serializedName)) {
31-
thrownewInvalidArgumentException(sprintf('Parameter of annotation "%s" must be a non-empty string.',static::class));
30+
if ('' ===$serializedName) {
31+
thrownewInvalidArgumentException(sprintf('Parameter of annotation "%s" must be a non-empty string.',self::class));
3232
}
3333
}
3434

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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+
namespaceSymfony\Component\Serializer\Annotation;
13+
14+
useSymfony\Component\Serializer\Exception\InvalidArgumentException;
15+
16+
/**
17+
* Annotation class for @SerializedPath().
18+
*
19+
* @Annotation
20+
*
21+
* @NamedArgumentConstructor
22+
*
23+
* @Target({"PROPERTY", "METHOD"})
24+
*
25+
* @author Tobias Bönner <tobi@boenner.family>
26+
*/
27+
#[\Attribute(\Attribute::TARGET_METHOD | \Attribute::TARGET_PROPERTY)]
28+
finalclass SerializedPath
29+
{
30+
publicfunction__construct(privatearray|string$serializedPath) {
31+
if ([] ===$serializedPath ||'' ===$serializedPath) {
32+
thrownewInvalidArgumentException(sprintf('Parameter of annotation "%s" must not be empty.',self::class));
33+
}
34+
}
35+
36+
publicfunctiongetSerializedPath():array
37+
{
38+
return (array)$this->serializedPath;
39+
}
40+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ 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`SerializedPath` annotation to flatten nested attributes
1415

1516
6.1
1617
---

‎src/Symfony/Component/Serializer/Mapping/AttributeMetadata.php‎

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,13 @@ class AttributeMetadata implements AttributeMetadataInterface
4848
*/
4949
public$serializedName;
5050

51+
/**
52+
* @internal This property is public in order to reduce the size of the
53+
* class' serialized representation. Do not access it. Use
54+
* {@link getSerializedPath()} instead.
55+
*/
56+
public ?array$serializedPath =null;
57+
5158
/**
5259
* @var bool
5360
*
@@ -121,6 +128,16 @@ public function getSerializedName(): ?string
121128
return$this->serializedName;
122129
}
123130

131+
publicfunctionsetSerializedPath(?array$serializedPath):void
132+
{
133+
$this->serializedPath =$serializedPath;
134+
}
135+
136+
publicfunctiongetSerializedPath(): ?array
137+
{
138+
return$this->serializedPath;
139+
}
140+
124141
publicfunctionsetIgnore(bool$ignore)
125142
{
126143
$this->ignore =$ignore;
@@ -190,14 +207,9 @@ public function merge(AttributeMetadataInterface $attributeMetadata)
190207
}
191208

192209
// Overwrite only if not defined
193-
if (null ===$this->maxDepth) {
194-
$this->maxDepth =$attributeMetadata->getMaxDepth();
195-
}
196-
197-
// Overwrite only if not defined
198-
if (null ===$this->serializedName) {
199-
$this->serializedName =$attributeMetadata->getSerializedName();
200-
}
210+
$this->maxDepth ??=$attributeMetadata->getMaxDepth();
211+
$this->serializedName ??=$attributeMetadata->getSerializedName();
212+
$this->serializedPath ??=$attributeMetadata->getSerializedPath();
201213

202214
// Overwrite only if both contexts are empty
203215
if (!$this->normalizationContexts && !$this->denormalizationContexts) {
@@ -217,6 +229,6 @@ public function merge(AttributeMetadataInterface $attributeMetadata)
217229
*/
218230
publicfunction__sleep():array
219231
{
220-
return ['name','groups','maxDepth','serializedName','ignore','normalizationContexts','denormalizationContexts'];
232+
return ['name','groups','maxDepth','serializedName','serializedPath','ignore','normalizationContexts','denormalizationContexts'];
221233
}
222234
}

‎src/Symfony/Component/Serializer/Mapping/AttributeMetadataInterface.php‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,10 @@ public function setSerializedName(?string $serializedName);
5959
*/
6060
publicfunctiongetSerializedName(): ?string;
6161

62+
publicfunctionsetSerializedPath(?array$serializedPath):void;
63+
64+
publicfunctiongetSerializedPath(): ?array;
65+
6266
/**
6367
* Sets if this attribute must be ignored or not.
6468
*/

‎src/Symfony/Component/Serializer/Mapping/Factory/ClassMetadataFactoryCompiler.php‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ private function generateDeclaredClassMetadata(array $classMetadatas): string
4848
$attributeMetadata->getGroups(),
4949
$attributeMetadata->getMaxDepth(),
5050
$attributeMetadata->getSerializedName(),
51+
$attributeMetadata->getSerializedPath(),
5152
];
5253
}
5354

‎src/Symfony/Component/Serializer/Mapping/Loader/AnnotationLoader.php‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
useSymfony\Component\Serializer\Annotation\Ignore;
1919
useSymfony\Component\Serializer\Annotation\MaxDepth;
2020
useSymfony\Component\Serializer\Annotation\SerializedName;
21+
useSymfony\Component\Serializer\Annotation\SerializedPath;
2122
useSymfony\Component\Serializer\Exception\MappingException;
2223
useSymfony\Component\Serializer\Mapping\AttributeMetadata;
2324
useSymfony\Component\Serializer\Mapping\AttributeMetadataInterface;
@@ -38,6 +39,7 @@ class AnnotationLoader implements LoaderInterface
3839
Ignore::class,
3940
MaxDepth::class,
4041
SerializedName::class,
42+
SerializedPath::class,
4143
Context::class,
4244
];
4345

@@ -81,6 +83,8 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool
8183
$attributesMetadata[$property->name]->setMaxDepth($annotation->getMaxDepth());
8284
}elseif ($annotationinstanceof SerializedName) {
8385
$attributesMetadata[$property->name]->setSerializedName($annotation->getSerializedName());
86+
}elseif ($annotationinstanceof SerializedPath) {
87+
$attributesMetadata[$property->name]->setSerializedPath($annotation->getSerializedPath());
8488
}elseif ($annotationinstanceof Ignore) {
8589
$attributesMetadata[$property->name]->setIgnore(true);
8690
}elseif ($annotationinstanceof Context) {
@@ -134,6 +138,12 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool
134138
}
135139

136140
$attributeMetadata->setSerializedName($annotation->getSerializedName());
141+
}elseif ($annotationinstanceof SerializedPath) {
142+
if (!$accessorOrMutator) {
143+
thrownewMappingException(sprintf('SerializedPath on "%s::%s()" cannot be added. SerializedPath can only be added on methods beginning with "get", "is", "has" or "set".',$className,$method->name));
144+
}
145+
146+
$attributeMetadata->setSerializedPath($annotation->getSerializedPath());
137147
}elseif ($annotationinstanceof Ignore) {
138148
if (!$accessorOrMutator) {
139149
thrownewMappingException(sprintf('Ignore on "%s::%s()" cannot be added. Ignore can only be added on methods beginning with "get", "is", "has" or "set".',$className,$method->name));

‎src/Symfony/Component/Serializer/Mapping/Loader/XmlFileLoader.php‎

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,10 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool
6868
$attributeMetadata->setSerializedName((string)$attribute['serialized-name']);
6969
}
7070

71+
if (isset($attribute->serialized_path)) {
72+
$attributeMetadata->setSerializedPath((array)$attribute->serialized_path->path);
73+
}
74+
7175
if (isset($attribute['ignore'])) {
7276
$attributeMetadata->setIgnore(XmlUtils::phpize($attribute['ignore']));
7377
}

‎src/Symfony/Component/Serializer/Mapping/Loader/YamlFileLoader.php‎

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,21 @@ public function loadClassMetadata(ClassMetadataInterface $classMetadata): bool
8484
}
8585

8686
if (isset($data['serialized_name'])) {
87-
if (!\is_string($data['serialized_name']) ||empty($data['serialized_name'])) {
87+
if (!\is_string($data['serialized_name']) ||'' ===$data['serialized_name']) {
8888
thrownewMappingException(sprintf('The "serialized_name" value must be a non-empty string in "%s" for the attribute "%s" of the class "%s".',$this->file,$attribute,$classMetadata->getName()));
8989
}
9090

9191
$attributeMetadata->setSerializedName($data['serialized_name']);
9292
}
9393

94+
if (isset($data['serialized_path'])) {
95+
if ('' ===$data['serialized_path'] || [] ===$data['serialized_path']) {
96+
thrownewMappingException(sprintf('The "serialized_path" value must not be empty in "%s" for the attribute "%s" of the class "%s".',$this->file,$attribute,$classMetadata->getName()));
97+
}
98+
99+
$attributeMetadata->setSerializedPath($data['serialized_path']);
100+
}
101+
94102
if (isset($data['ignore'])) {
95103
if (!\is_bool($data['ignore'])) {
96104
thrownewMappingException(sprintf('The "ignore" value must be a boolean in "%s" for the attribute "%s" of the class "%s".',$this->file,$attribute,$classMetadata->getName()));

‎src/Symfony/Component/Serializer/Mapping/Loader/schema/dic/serializer-mapping/serializer-mapping-1.0.xsd‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,7 @@
6565
<xsd:elementname="context"type="context"maxOccurs="unbounded" />
6666
<xsd:elementname="normalization_context"type="context"maxOccurs="unbounded" />
6767
<xsd:elementname="denormalization_context"type="context"maxOccurs="unbounded" />
68+
<xsd:elementname="serialized_path"type="path"maxOccurs="1" />
6869
</xsd:choice>
6970
<xsd:attributename="name"type="xsd:string"use="required" />
7071
<xsd:attributename="max-depth">
@@ -84,6 +85,12 @@
8485
<xsd:attributename="ignore"type="xsd:boolean" />
8586
</xsd:complexType>
8687

88+
<xsd:complexTypename="path">
89+
<xsd:sequenceminOccurs="1">
90+
<xsd:elementname="path"type="xsd:string"minOccurs="1"maxOccurs="unbounded" />
91+
</xsd:sequence>
92+
</xsd:complexType>
93+
8794
<xsd:complexTypename="context">
8895
<xsd:choicemaxOccurs="unbounded">
8996
<xsd:elementname="group"type="xsd:string"minOccurs="0"maxOccurs="unbounded" />

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp