[Serializer] Allow options to be passed to SerialiizerInterface#serialize and #unserialize. Thsee options are available to all encoders/decoders/normalizers that implement SerializerAwareInterface.

This commit is contained in:
Benjamin Eberlei 2012-07-16 11:01:52 +02:00 committed by Florin Patan
parent 31ff3db517
commit 9c54a4b552
4 changed files with 69 additions and 12 deletions

View File

@ -39,11 +39,11 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
$this->format = $format;
if (null !== $data && !is_scalar($data)) {
$root = $this->dom->createElement($this->rootNodeName);
$root = $this->dom->createElement($this->getRealRootNodeName());
$this->dom->appendChild($root);
$this->buildXml($root, $data);
} else {
$this->appendNode($this->dom, $data, $this->rootNodeName);
$this->appendNode($this->dom, $data, $this->getRealRootNodeName());
}
return $this->dom->saveXML();
@ -320,7 +320,7 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
$root = $parentNode->parentNode;
$root->removeChild($parentNode);
return $this->appendNode($root, $data, $this->rootNodeName);
return $this->appendNode($root, $data, $this->getRealRootNodeName());
}
return $this->appendNode($parentNode, $data, 'data');
@ -399,4 +399,21 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
return true;
}
/**
* Get real XML root node name, taking serializer options into account.
*/
private function getRealRootNodeName()
{
if ( ! $this->serializer) {
return $this->rootNodeName;
}
$options = $this->serializer->getOptions();
return isset($options['xml_root_node_name'])
? $options['xml_root_node_name']
: $this->rootNodeName;
}
}

View File

@ -39,11 +39,12 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
{
protected $encoder;
protected $decoder;
protected $normalizers = array();
protected $normalizerCache = array();
protected $normalizers = array();
protected $normalizerCache = array();
protected $denormalizerCache = array();
protected $options = array();
public function __construct(array $normalizers = array(), array $encoders = array())
public function __construct(array $normalizers = array(), array $encoders = array(), array $options = array())
{
foreach ($normalizers as $normalizer) {
if ($normalizer instanceof SerializerAwareInterface) {
@ -67,17 +68,20 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
}
$this->encoder = new ChainEncoder($realEncoders);
$this->decoder = new ChainDecoder($decoders);
$this->options = $options;
}
/**
* {@inheritdoc}
*/
final public function serialize($data, $format)
final public function serialize($data, $format, array $options = array())
{
if (!$this->supportsEncoding($format)) {
throw new UnexpectedValueException('Serialization for the format '.$format.' is not supported');
}
$this->options = array_merge($this->options, $options);
if ($this->encoder->needsNormalization($format)) {
$data = $this->normalize($data, $format);
}
@ -88,12 +92,14 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
/**
* {@inheritdoc}
*/
final public function deserialize($data, $type, $format)
final public function deserialize($data, $type, $format, array $options = array())
{
if (!$this->supportsDecoding($format)) {
throw new UnexpectedValueException('Deserialization for the format '.$format.' is not supported');
}
$this->options = array_merge($this->options, $options);
$data = $this->decode($data, $format);
return $this->denormalize($data, $type, $format);
@ -296,4 +302,12 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
{
return $this->decoder->supportsDecoding($format);
}
/**
* {@inheritdoc}
*/
public function getOptions()
{
return $this->options;
}
}

View File

@ -21,12 +21,13 @@ interface SerializerInterface
/**
* Serializes data in the appropriate format
*
* @param mixed $data any data
* @param string $format format name
* @param mixed $data any data
* @param string $format format name
* @param array $options options normalizers/encoders have access to
*
* @return string
*/
public function serialize($data, $format);
function serialize($data, $format, array $options = array());
/**
* Deserializes data into the given type.
@ -34,8 +35,16 @@ interface SerializerInterface
* @param mixed $data
* @param string $type
* @param string $format
* @param array $options
*
* @return object
*/
public function deserialize($data, $type, $format);
function deserialize($data, $type, $format, array $options = array());
/**
* Get current options of the serializer
*
* @return array
*/
function getOptions();
}

View File

@ -184,6 +184,23 @@ class XmlEncoderTest extends \PHPUnit_Framework_TestCase
$this->assertEquals($source, $this->encoder->encode($obj, 'xml'));
}
public function testEncodeSerializerXmlRootNodeNameOption()
{
$options = array('xml_root_node_name' => 'test');
$this->encoder = new XmlEncoder;
$serializer = new Serializer(array(), array('xml' => new XmlEncoder()), $options);
$this->encoder->setSerializer($serializer);
$array = array(
'person' => array('@gender' => 'M', '#' => 'Peter'),
);
$expected = '<?xml version="1.0"?>'."\n".
'<test><person gender="M">Peter</person></test>'."\n";
$this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
}
public function testDecode()
{
$source = $this->getXmlSource();