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

Commit0ab3beb

Browse files
committed
feature#13257 [Serializer] ObjectNormalizer (dunglas)
This PR was merged into the 2.7 branch.Discussion----------[Serializer] ObjectNormalizer| Q | A| ------------- | ---| Bug fix? | no| New feature? | yes| BC breaks? | no| Deprecations? | no| Tests pass? | yes| License | MIT| Doc PR | not yet`PropertyAccessNormalizer` is a new normalizer leveraging the PropertyAccess Component. It is able to handle classes containing both public properties and properties only accessibles trough getters / setters / issers / hassers...As it extends `AbstractNormalizer`, it supports circular reference handling, name converters and existing object population.What do you think about making this new normalizer the default one as it's the most convenient to use and the most consistent with the behavior of other components.#13120,#13252 and#13255 need to be merged to make this PR working.Commits-------0050bbb [Serializer] Introduce ObjectNormalizer
2 parentsff70902 +0050bbb commit0ab3beb

File tree

4 files changed

+664
-1
lines changed

4 files changed

+664
-1
lines changed

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ CHANGELOG
1515
`PropertyNormalizer::setCamelizedAttributes()` are replaced by
1616
`CamelCaseToSnakeCaseNameConverter`
1717
*[DEPRECATION] the`Exception` interface has been renamed to`ExceptionInterface`
18+
* added`ObjectNormalizer` leveraging the`PropertyAccess` component to normalize
19+
objects containing both properties and getters / setters / issers / hassers methods.
1820

1921
2.6.0
2022
-----
Lines changed: 162 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,162 @@
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\Normalizer;
13+
14+
useSymfony\Component\PropertyAccess\Exception\NoSuchPropertyException;
15+
useSymfony\Component\PropertyAccess\PropertyAccess;
16+
useSymfony\Component\PropertyAccess\PropertyAccessorInterface;
17+
useSymfony\Component\Serializer\Exception\CircularReferenceException;
18+
useSymfony\Component\Serializer\Exception\LogicException;
19+
useSymfony\Component\Serializer\Mapping\Factory\ClassMetadataFactoryInterface;
20+
useSymfony\Component\Serializer\NameConverter\NameConverterInterface;
21+
22+
/**
23+
* Converts between objects and arrays using the PropertyAccess component.
24+
*
25+
* @author Kévin Dunglas <dunglas@gmail.com>
26+
*/
27+
class ObjectNormalizerextends AbstractNormalizer
28+
{
29+
/**
30+
* @var PropertyAccessorInterface
31+
*/
32+
protected$propertyAccessor;
33+
34+
publicfunction__construct(ClassMetadataFactoryInterface$classMetadataFactory =null,NameConverterInterface$nameConverter =null,PropertyAccessorInterface$propertyAccessor =null)
35+
{
36+
parent::__construct($classMetadataFactory,$nameConverter);
37+
38+
$this->propertyAccessor =$propertyAccessor ?: PropertyAccess::createPropertyAccessor();
39+
}
40+
41+
/**
42+
* {@inheritdoc}
43+
*/
44+
publicfunctionsupportsNormalization($data,$format =null)
45+
{
46+
returnis_object($data);
47+
}
48+
49+
/**
50+
* {@inheritdoc}
51+
*
52+
* @throws CircularReferenceException
53+
*/
54+
publicfunctionnormalize($object,$format =null,array$context =array())
55+
{
56+
if ($this->isCircularReference($object,$context)) {
57+
return$this->handleCircularReference($object);
58+
}
59+
60+
$data =array();
61+
$attributes =$this->getAllowedAttributes($object,$context,true);
62+
63+
// If not using groups, detect manually
64+
if (false ===$attributes) {
65+
$attributes =array();
66+
67+
// methods
68+
$reflClass =new \ReflectionClass($object);
69+
foreach ($reflClass->getMethods(\ReflectionMethod::IS_PUBLIC)as$reflMethod) {
70+
if (
71+
!$reflMethod->isConstructor() &&
72+
!$reflMethod->isDestructor() &&
73+
0 ===$reflMethod->getNumberOfRequiredParameters()
74+
) {
75+
$name =$reflMethod->getName();
76+
77+
if (strpos($name,'get') ===0 ||strpos($name,'has') ===0) {
78+
// getters and hassers
79+
$attributes[lcfirst(substr($name,3))] =true;
80+
}elseif (strpos($name,'is') ===0) {
81+
// issers
82+
$attributes[lcfirst(substr($name,2))] =true;
83+
}
84+
}
85+
}
86+
87+
// properties
88+
foreach ($reflClass->getProperties(\ReflectionProperty::IS_PUBLIC)as$reflProperty) {
89+
$attributes[$reflProperty->getName()] =true;
90+
}
91+
92+
$attributes =array_keys($attributes);
93+
}
94+
95+
foreach ($attributesas$attribute) {
96+
if (in_array($attribute,$this->ignoredAttributes)) {
97+
continue;
98+
}
99+
100+
$attributeValue =$this->propertyAccessor->getValue($object,$attribute);
101+
102+
if (isset($this->callbacks[$attribute])) {
103+
$attributeValue =call_user_func($this->callbacks[$attribute],$attributeValue);
104+
}
105+
106+
if (null !==$attributeValue && !is_scalar($attributeValue)) {
107+
if (!$this->serializerinstanceof NormalizerInterface) {
108+
thrownewLogicException(sprintf('Cannot normalize attribute "%s" because injected serializer is not a normalizer',$attribute));
109+
}
110+
111+
$attributeValue =$this->serializer->normalize($attributeValue,$format,$context);
112+
}
113+
114+
if ($this->nameConverter) {
115+
$attribute =$this->nameConverter->normalize($attribute);
116+
}
117+
118+
$data[$attribute] =$attributeValue;
119+
}
120+
121+
return$data;
122+
}
123+
124+
/**
125+
* {@inheritdoc}
126+
*/
127+
publicfunctionsupportsDenormalization($data,$type,$format =null)
128+
{
129+
returnclass_exists($type);
130+
}
131+
132+
/**
133+
* {@inheritdoc}
134+
*/
135+
publicfunctiondenormalize($data,$class,$format =null,array$context =array())
136+
{
137+
$allowedAttributes =$this->getAllowedAttributes($class,$context,true);
138+
$normalizedData =$this->prepareForDenormalization($data);
139+
140+
$reflectionClass =new \ReflectionClass($class);
141+
$object =$this->instantiateObject($normalizedData,$class,$context,$reflectionClass,$allowedAttributes);
142+
143+
foreach ($normalizedDataas$attribute =>$value) {
144+
$allowed =$allowedAttributes ===false ||in_array($attribute,$allowedAttributes);
145+
$ignored =in_array($attribute,$this->ignoredAttributes);
146+
147+
if ($allowed && !$ignored) {
148+
if ($this->nameConverter) {
149+
$attribute =$this->nameConverter->normalize($attribute);
150+
}
151+
152+
try {
153+
$this->propertyAccessor->setValue($object,$attribute,$value);
154+
}catch (NoSuchPropertyException$exception) {
155+
// Properties not found are ignored
156+
}
157+
}
158+
}
159+
160+
return$object;
161+
}
162+
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp