Skip to content

Commit c1740fc

Browse files
committed
[Serializer] ObjectNormalizer: context can contain not serializable data
1 parent 5da874d commit c1740fc

File tree

2 files changed

+45
-11
lines changed

2 files changed

+45
-11
lines changed

src/Symfony/Component/Serializer/Normalizer/ObjectNormalizer.php

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@
2626
*/
2727
class ObjectNormalizer extends AbstractNormalizer
2828
{
29-
private static $attributesCache = array();
29+
private $attributesCache = array();
3030

3131
/**
3232
* @var PropertyAccessorInterface
@@ -136,20 +136,39 @@ public function denormalize($data, $class, $format = null, array $context = arra
136136
* @param object $object
137137
* @param array $context
138138
*
139-
* @return array
139+
* @return string[]
140140
*/
141141
private function getAttributes($object, array $context)
142142
{
143-
$key = sprintf('%s-%s', get_class($object), serialize($context));
143+
try {
144+
$serializedContext = serialize($context);
145+
} catch (\Exception $exception) {
146+
// The context cannot be serialized, skip the cache
147+
return $this->extractAttributes($object, $context);
148+
}
149+
150+
$key = sprintf('%s-%s', get_class($object), $serializedContext);
144151

145-
if (isset(self::$attributesCache[$key])) {
146-
return self::$attributesCache[$key];
152+
if (isset($this->attributesCache[$key])) {
153+
return $this->attributesCache[$key];
147154
}
148155

149-
$allowedAttributes = $this->getAllowedAttributes($object, $context, true);
156+
return $this->attributesCache[$key] = $this->extractAttributes($object, $context);
157+
}
150158

159+
/**
160+
* Extracts attributes for this class and context.
161+
*
162+
* @param object $object
163+
* @param array $context
164+
*
165+
* @return string[]
166+
*/
167+
private function extractAttributes($object, array $context)
168+
{
169+
$allowedAttributes = $this->getAllowedAttributes($object, $context, true);
151170
if (false !== $allowedAttributes) {
152-
return self::$attributesCache[$key] = $allowedAttributes;
171+
return $allowedAttributes;
153172
}
154173

155174
// If not using groups, detect manually
@@ -167,9 +186,9 @@ private function getAttributes($object, array $context)
167186
continue;
168187
}
169188

170-
$name = $reflMethod->getName();
189+
$name = $reflMethod->name;
171190

172-
if (strpos($name, 'get') === 0 || strpos($name, 'has') === 0) {
191+
if (0 === strpos($name, 'get') || 0 === strpos($name, 'has')) {
173192
// getters and hassers
174193
$attributes[lcfirst(substr($name, 3))] = true;
175194
} elseif (strpos($name, 'is') === 0) {
@@ -184,9 +203,9 @@ private function getAttributes($object, array $context)
184203
continue;
185204
}
186205

187-
$attributes[$reflProperty->getName()] = true;
206+
$attributes[$reflProperty->name] = true;
188207
}
189208

190-
return self::$attributesCache[$key] = array_keys($attributes);
209+
return array_keys($attributes);
191210
}
192211
}

src/Symfony/Component/Serializer/Tests/Normalizer/ObjectNormalizerTest.php

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -473,6 +473,21 @@ public function testNormalizeStatic()
473473
{
474474
$this->assertEquals(array('foo' => 'K'), $this->normalizer->normalize(new ObjectWithStaticPropertiesAndMethods()));
475475
}
476+
477+
public function testNormalizeNotSerializableContext()
478+
{
479+
$objectDummy = new ObjectDummy();
480+
$expected = array(
481+
'foo' => null,
482+
'baz' => null,
483+
'fooBar' => '',
484+
'camelCase' => null,
485+
'object' => null,
486+
'bar' => null,
487+
);
488+
489+
$this->assertEquals($expected, $this->normalizer->normalize($objectDummy, null, array('not_serializable' => function () {})));
490+
}
476491
}
477492

478493
class ObjectDummy

0 commit comments

Comments
 (0)