Skip to content

Commit b316d4f

Browse files
committed
merged branch ericclemmons/2295-serializer-normalizable-traversable (PR #2578)
Commits ------- 7346896 Changed Serialized#supportsNormalization to PRIVATE e851efc Updated SerializerTest with "normalizeTraversable" & "testNormalizeGivesPriorityToInterfaceOverTraversable" d789f94 Serializer#normalize gives precedence to objects that support normalization 9e6ba9a Added protected Serializer#supportsNormalization Discussion ---------- [Serializer] `normalize` should use supported normalizer before Traversable Bug fix: yes Feature addition: no Backwards compatibility break: no (discussion needed) Symfony2 tests pass: yes Fixes the following tickets: #2295 **Same as PR #2539, except rebased onto `2.0`** Should I abstract out a `supportsDenormalization` function just for symmetry?
2 parents 1a5b923 + 682c218 commit b316d4f

File tree

1 file changed

+32
-7
lines changed

1 file changed

+32
-7
lines changed

Serializer.php

Lines changed: 32 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,9 @@ public function normalize($data, $format = null)
9696
if (null === $data || is_scalar($data)) {
9797
return $data;
9898
}
99+
if (is_object($data) && $this->supportsNormalization($data, $format)) {
100+
return $this->normalizeObject($data, $format);
101+
}
99102
if ($data instanceof \Traversable) {
100103
$normalized = array();
101104
foreach ($data as $key => $val) {
@@ -153,17 +156,14 @@ private function normalizeObject($object, $format = null)
153156
if (!$this->normalizers) {
154157
throw new LogicException('You must register at least one normalizer to be able to normalize objects.');
155158
}
159+
156160
$class = get_class($object);
157-
if (isset($this->normalizerCache[$class][$format])) {
161+
162+
// If normalization is supported, cached normalizer will exist
163+
if ($this->supportsNormalization($object, $format)) {
158164
return $this->normalizerCache[$class][$format]->normalize($object, $format);
159165
}
160-
foreach ($this->normalizers as $normalizer) {
161-
if ($normalizer->supportsNormalization($object, $class, $format)) {
162-
$this->normalizerCache[$class][$format] = $normalizer;
163166

164-
return $normalizer->normalize($object, $format);
165-
}
166-
}
167167
throw new UnexpectedValueException('Could not normalize object of type '.$class.', no supporting normalizer found.');
168168
}
169169

@@ -193,6 +193,31 @@ private function denormalizeObject($data, $class, $format = null)
193193
throw new UnexpectedValueException('Could not denormalize object of type '.$class.', no supporting normalizer found.');
194194
}
195195

196+
/**
197+
* Check if normalizer cache or normalizers supports provided object, which will then be cached
198+
*
199+
* @param object $object Object to test for normalization support
200+
* @param string $format Format name, needed for normalizers to pivot on
201+
*/
202+
private function supportsNormalization($object, $format)
203+
{
204+
$class = get_class($object);
205+
206+
if (isset($this->normalizerCache[$class][$format])) {
207+
return true;
208+
}
209+
210+
foreach ($this->normalizers as $normalizer) {
211+
if ($normalizer->supportsNormalization($object, $format)) {
212+
$this->normalizerCache[$class][$format] = $normalizer;
213+
214+
return true;
215+
}
216+
}
217+
218+
return false;
219+
}
220+
196221
/**
197222
* {@inheritdoc}
198223
*/

0 commit comments

Comments
 (0)