Skip to content

Commit e8e7f1b

Browse files
committed
Merge branch '2.8'
* 2.8: [HttpKernel] clearstatcache() so the Cache sees when a .lck file has been released [WIP] [Form] [TwigBridge] Bootstrap horizontal theme missing tests [Serializer] Improve ObjectNormalizer performance AssetBundle - fix docs [Yaml] more fixes to changelog and upgrade files CS: remove impossible default argument value
2 parents 1f23dd9 + aab4ce7 commit e8e7f1b

File tree

2 files changed

+76
-37
lines changed

2 files changed

+76
-37
lines changed

Normalizer/ObjectNormalizer.php

Lines changed: 63 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
*/
2727
class ObjectNormalizer extends AbstractNormalizer
2828
{
29+
private static $attributesCache = array();
30+
2931
/**
3032
* @var PropertyAccessorInterface
3133
*/
@@ -58,42 +60,7 @@ public function normalize($object, $format = null, array $context = array())
5860
}
5961

6062
$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->isStatic() &&
72-
!$reflMethod->isConstructor() &&
73-
!$reflMethod->isDestructor() &&
74-
0 === $reflMethod->getNumberOfRequiredParameters()
75-
) {
76-
$name = $reflMethod->getName();
77-
78-
if (strpos($name, 'get') === 0 || strpos($name, 'has') === 0) {
79-
// getters and hassers
80-
$attributes[lcfirst(substr($name, 3))] = true;
81-
} elseif (strpos($name, 'is') === 0) {
82-
// issers
83-
$attributes[lcfirst(substr($name, 2))] = true;
84-
}
85-
}
86-
}
87-
88-
// properties
89-
foreach ($reflClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $reflProperty) {
90-
if (!$reflProperty->isStatic()) {
91-
$attributes[$reflProperty->getName()] = true;
92-
}
93-
}
94-
95-
$attributes = array_keys($attributes);
96-
}
63+
$attributes = $this->getAttributes($object, $context);
9764

9865
foreach ($attributes as $attribute) {
9966
if (in_array($attribute, $this->ignoredAttributes)) {
@@ -162,4 +129,64 @@ public function denormalize($data, $class, $format = null, array $context = arra
162129

163130
return $object;
164131
}
132+
133+
/**
134+
* Gets and caches attributes for this class and context.
135+
*
136+
* @param object $object
137+
* @param array $context
138+
*
139+
* @return array
140+
*/
141+
private function getAttributes($object, array $context)
142+
{
143+
$key = sprintf('%s-%s', get_class($object), serialize($context));
144+
145+
if (isset(self::$attributesCache[$key])) {
146+
return self::$attributesCache[$key];
147+
}
148+
149+
$allowedAttributes = $this->getAllowedAttributes($object, $context, true);
150+
151+
if (false !== $allowedAttributes) {
152+
return self::$attributesCache[$key] = $allowedAttributes;
153+
}
154+
155+
// If not using groups, detect manually
156+
$attributes = array();
157+
158+
// methods
159+
$reflClass = new \ReflectionClass($object);
160+
foreach ($reflClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $reflMethod) {
161+
if (
162+
$reflMethod->getNumberOfRequiredParameters() !== 0 ||
163+
$reflMethod->isStatic() ||
164+
$reflMethod->isConstructor() ||
165+
$reflMethod->isDestructor()
166+
) {
167+
continue;
168+
}
169+
170+
$name = $reflMethod->getName();
171+
172+
if (strpos($name, 'get') === 0 || strpos($name, 'has') === 0) {
173+
// getters and hassers
174+
$attributes[lcfirst(substr($name, 3))] = true;
175+
} elseif (strpos($name, 'is') === 0) {
176+
// issers
177+
$attributes[lcfirst(substr($name, 2))] = true;
178+
}
179+
}
180+
181+
// properties
182+
foreach ($reflClass->getProperties(\ReflectionProperty::IS_PUBLIC) as $reflProperty) {
183+
if ($reflProperty->isStatic()) {
184+
continue;
185+
}
186+
187+
$attributes[$reflProperty->getName()] = true;
188+
}
189+
190+
return self::$attributesCache[$key] = array_keys($attributes);
191+
}
165192
}

Tests/Normalizer/ObjectNormalizerTest.php

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@
2929
class ObjectNormalizerTest extends \PHPUnit_Framework_TestCase
3030
{
3131
/**
32-
* @var ObjectNormalizerTest
32+
* @var ObjectNormalizer
3333
*/
3434
private $normalizer;
3535
/**
@@ -211,6 +211,18 @@ public function testGroupsDenormalize()
211211
$this->assertEquals($obj, $normalized);
212212
}
213213

214+
public function testNormalizeNoPropertyInGroup()
215+
{
216+
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));
217+
$this->normalizer = new ObjectNormalizer($classMetadataFactory);
218+
$this->normalizer->setSerializer($this->serializer);
219+
220+
$obj = new GroupDummy();
221+
$obj->setFoo('foo');
222+
223+
$this->assertEquals(array(), $this->normalizer->normalize($obj, null, array('groups' => array('notExist'))));
224+
}
225+
214226
public function testGroupsNormalizeWithNameConverter()
215227
{
216228
$classMetadataFactory = new ClassMetadataFactory(new AnnotationLoader(new AnnotationReader()));

0 commit comments

Comments
 (0)