Skip to content

Commit 3e7a28f

Browse files
beberleidlsniper
authored andcommitted
[Serializer] Allow options to be passed to SerialiizerInterface#serialize and #unserialize. Thsee options are available to all encoders/decoders/normalizers that implement SerializerAwareInterface.
1 parent 2c77ccb commit 3e7a28f

File tree

4 files changed

+69
-12
lines changed

4 files changed

+69
-12
lines changed

Encoder/XmlEncoder.php

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,11 @@ public function encode($data, $format)
3939
$this->format = $format;
4040

4141
if (null !== $data && !is_scalar($data)) {
42-
$root = $this->dom->createElement($this->rootNodeName);
42+
$root = $this->dom->createElement($this->getRealRootNodeName());
4343
$this->dom->appendChild($root);
4444
$this->buildXml($root, $data);
4545
} else {
46-
$this->appendNode($this->dom, $data, $this->rootNodeName);
46+
$this->appendNode($this->dom, $data, $this->getRealRootNodeName());
4747
}
4848

4949
return $this->dom->saveXML();
@@ -320,7 +320,7 @@ private function buildXml($parentNode, $data)
320320
$root = $parentNode->parentNode;
321321
$root->removeChild($parentNode);
322322

323-
return $this->appendNode($root, $data, $this->rootNodeName);
323+
return $this->appendNode($root, $data, $this->getRealRootNodeName());
324324
}
325325

326326
return $this->appendNode($parentNode, $data, 'data');
@@ -399,4 +399,21 @@ private function selectNodeType($node, $val)
399399

400400
return true;
401401
}
402+
403+
/**
404+
* Get real XML root node name, taking serializer options into account.
405+
*/
406+
private function getRealRootNodeName()
407+
{
408+
if ( ! $this->serializer) {
409+
return $this->rootNodeName;
410+
}
411+
412+
$options = $this->serializer->getOptions();
413+
414+
return isset($options['xml_root_node_name'])
415+
? $options['xml_root_node_name']
416+
: $this->rootNodeName;
417+
}
418+
402419
}

Serializer.php

Lines changed: 19 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,11 +39,12 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
3939
{
4040
protected $encoder;
4141
protected $decoder;
42-
protected $normalizers = array();
43-
protected $normalizerCache = array();
42+
protected $normalizers = array();
43+
protected $normalizerCache = array();
4444
protected $denormalizerCache = array();
45+
protected $options = array();
4546

46-
public function __construct(array $normalizers = array(), array $encoders = array())
47+
public function __construct(array $normalizers = array(), array $encoders = array(), array $options = array())
4748
{
4849
foreach ($normalizers as $normalizer) {
4950
if ($normalizer instanceof SerializerAwareInterface) {
@@ -67,17 +68,20 @@ public function __construct(array $normalizers = array(), array $encoders = arra
6768
}
6869
$this->encoder = new ChainEncoder($realEncoders);
6970
$this->decoder = new ChainDecoder($decoders);
71+
$this->options = $options;
7072
}
7173

7274
/**
7375
* {@inheritdoc}
7476
*/
75-
final public function serialize($data, $format)
77+
final public function serialize($data, $format, array $options = array())
7678
{
7779
if (!$this->supportsEncoding($format)) {
7880
throw new UnexpectedValueException('Serialization for the format '.$format.' is not supported');
7981
}
8082

83+
$this->options = array_merge($this->options, $options);
84+
8185
if ($this->encoder->needsNormalization($format)) {
8286
$data = $this->normalize($data, $format);
8387
}
@@ -88,12 +92,14 @@ final public function serialize($data, $format)
8892
/**
8993
* {@inheritdoc}
9094
*/
91-
final public function deserialize($data, $type, $format)
95+
final public function deserialize($data, $type, $format, array $options = array())
9296
{
9397
if (!$this->supportsDecoding($format)) {
9498
throw new UnexpectedValueException('Deserialization for the format '.$format.' is not supported');
9599
}
96100

101+
$this->options = array_merge($this->options, $options);
102+
97103
$data = $this->decode($data, $format);
98104

99105
return $this->denormalize($data, $type, $format);
@@ -296,4 +302,12 @@ public function supportsDecoding($format)
296302
{
297303
return $this->decoder->supportsDecoding($format);
298304
}
305+
306+
/**
307+
* {@inheritdoc}
308+
*/
309+
public function getOptions()
310+
{
311+
return $this->options;
312+
}
299313
}

SerializerInterface.php

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,21 +21,30 @@ interface SerializerInterface
2121
/**
2222
* Serializes data in the appropriate format
2323
*
24-
* @param mixed $data any data
25-
* @param string $format format name
24+
* @param mixed $data any data
25+
* @param string $format format name
26+
* @param array $options options normalizers/encoders have access to
2627
*
2728
* @return string
2829
*/
29-
public function serialize($data, $format);
30+
function serialize($data, $format, array $options = array());
3031

3132
/**
3233
* Deserializes data into the given type.
3334
*
3435
* @param mixed $data
3536
* @param string $type
3637
* @param string $format
38+
* @param array $options
3739
*
3840
* @return object
3941
*/
40-
public function deserialize($data, $type, $format);
42+
function deserialize($data, $type, $format, array $options = array());
43+
44+
/**
45+
* Get current options of the serializer
46+
*
47+
* @return array
48+
*/
49+
function getOptions();
4150
}

Tests/Encoder/XmlEncoderTest.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,23 @@ public function testEncode()
184184
$this->assertEquals($source, $this->encoder->encode($obj, 'xml'));
185185
}
186186

187+
public function testEncodeSerializerXmlRootNodeNameOption()
188+
{
189+
$options = array('xml_root_node_name' => 'test');
190+
$this->encoder = new XmlEncoder;
191+
$serializer = new Serializer(array(), array('xml' => new XmlEncoder()), $options);
192+
$this->encoder->setSerializer($serializer);
193+
194+
$array = array(
195+
'person' => array('@gender' => 'M', '#' => 'Peter'),
196+
);
197+
198+
$expected = '<?xml version="1.0"?>'."\n".
199+
'<test><person gender="M">Peter</person></test>'."\n";
200+
201+
$this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
202+
}
203+
187204
public function testDecode()
188205
{
189206
$source = $this->getXmlSource();

0 commit comments

Comments
 (0)