Completly refactor the Serializer Options Pull Request to push context information directly and avoid state and dependencies between SerializerInterface and encoders/normalizers.
This commit is contained in:
parent
ef652e2d8f
commit
b6bdb450e3
|
@ -383,3 +383,9 @@
|
||||||
framework:
|
framework:
|
||||||
trusted_proxies: ['127.0.0.1', '10.0.0.1'] # a list of proxy IPs you trust
|
trusted_proxies: ['127.0.0.1', '10.0.0.1'] # a list of proxy IPs you trust
|
||||||
```
|
```
|
||||||
|
|
||||||
|
#### Serializer
|
||||||
|
|
||||||
|
* All serializer interfaces (Serializer, Normalizer, Encoder) have been extended with an optional ``$context`` array.
|
||||||
|
This was necessary to allow for more complex use-cases that require context information during the (de)normalization
|
||||||
|
and en-/decoding steps.
|
||||||
|
|
|
@ -34,9 +34,9 @@ class ChainDecoder implements DecoderInterface
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
final public function decode($data, $format)
|
final public function decode($data, $format, array $context = array())
|
||||||
{
|
{
|
||||||
return $this->getDecoder($format)->decode($data, $format);
|
return $this->getDecoder($format)->decode($data, $format, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -35,9 +35,9 @@ class ChainEncoder implements EncoderInterface
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
final public function encode($data, $format)
|
final public function encode($data, $format, array $context = array())
|
||||||
{
|
{
|
||||||
return $this->getEncoder($format)->encode($data, $format);
|
return $this->getEncoder($format)->encode($data, $format, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -23,10 +23,11 @@ interface DecoderInterface
|
||||||
*
|
*
|
||||||
* @param scalar $data Data to decode
|
* @param scalar $data Data to decode
|
||||||
* @param string $format Format name
|
* @param string $format Format name
|
||||||
|
* @param array $context options that decoders have access to.
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function decode($data, $format);
|
public function decode($data, $format, array $context = array());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the serializer can decode from given format
|
* Checks whether the serializer can decode from given format
|
||||||
|
|
|
@ -23,10 +23,11 @@ interface EncoderInterface
|
||||||
*
|
*
|
||||||
* @param mixed $data Data to encode
|
* @param mixed $data Data to encode
|
||||||
* @param string $format Format name
|
* @param string $format Format name
|
||||||
|
* @param array $context options that normalizers/encoders have access to.
|
||||||
*
|
*
|
||||||
* @return scalar
|
* @return scalar
|
||||||
*/
|
*/
|
||||||
public function encode($data, $format);
|
public function encode($data, $format, array $context = array());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the serializer can encode to given format
|
* Checks whether the serializer can encode to given format
|
||||||
|
|
|
@ -11,15 +11,12 @@
|
||||||
|
|
||||||
namespace Symfony\Component\Serializer\Encoder;
|
namespace Symfony\Component\Serializer\Encoder;
|
||||||
|
|
||||||
use Symfony\Component\Serializer\SerializerInterface;
|
|
||||||
use Symfony\Component\Serializer\SerializerAwareInterface;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Decodes JSON data
|
* Decodes JSON data
|
||||||
*
|
*
|
||||||
* @author Sander Coolen <sander@jibber.nl>
|
* @author Sander Coolen <sander@jibber.nl>
|
||||||
*/
|
*/
|
||||||
class JsonDecode implements DecoderInterface, SerializerAwareInterface
|
class JsonDecode implements DecoderInterface
|
||||||
{
|
{
|
||||||
private $associative;
|
private $associative;
|
||||||
private $recursionDepth;
|
private $recursionDepth;
|
||||||
|
@ -52,13 +49,13 @@ class JsonDecode implements DecoderInterface, SerializerAwareInterface
|
||||||
*
|
*
|
||||||
* @return mixed
|
* @return mixed
|
||||||
*/
|
*/
|
||||||
public function decode($data, $format)
|
public function decode($data, $format, array $context = array())
|
||||||
{
|
{
|
||||||
$context = $this->getContext();
|
$context = $this->resolveContext($context);
|
||||||
|
|
||||||
$associative = $context['associative'];
|
$associative = $context['json_decode_associative'];
|
||||||
$recursionDepth = $context['recursionDepth'];
|
$recursionDepth = $context['json_decode_recursion_depth'];
|
||||||
$options = $context['options'];
|
$options = $context['json_decode_options'];
|
||||||
|
|
||||||
$decodedData = json_decode($data, $associative, $recursionDepth, $options);
|
$decodedData = json_decode($data, $associative, $recursionDepth, $options);
|
||||||
$this->lastError = json_last_error();
|
$this->lastError = json_last_error();
|
||||||
|
@ -75,45 +72,19 @@ class JsonDecode implements DecoderInterface, SerializerAwareInterface
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* Merge the default options of the Json Decoder with the passed context.
|
||||||
|
*
|
||||||
|
* @param array $context
|
||||||
|
* @return array
|
||||||
*/
|
*/
|
||||||
public function setSerializer(SerializerInterface $serializer)
|
private function resolveContext(array $context)
|
||||||
{
|
{
|
||||||
$this->serializer = $serializer;
|
$defaultOptions = array(
|
||||||
}
|
'json_decode_associative' => $this->associative,
|
||||||
|
'json_decode_recursion_depth' => $this->recursionDepth,
|
||||||
private function getContext()
|
'json_decode_options' => 0
|
||||||
{
|
|
||||||
$options = array(
|
|
||||||
'associative' => $this->associative,
|
|
||||||
'recursionDepth' => $this->recursionDepth,
|
|
||||||
'options' => 0
|
|
||||||
);
|
);
|
||||||
|
|
||||||
if (!$this->serializer) {
|
return array_merge($defaultOptions, $context);
|
||||||
return $options;
|
|
||||||
}
|
|
||||||
|
|
||||||
$options = array(
|
|
||||||
'associative' => false,
|
|
||||||
'recursionDepth' => 512,
|
|
||||||
'options' => 0
|
|
||||||
);
|
|
||||||
|
|
||||||
$context = $this->serializer->getContext();
|
|
||||||
|
|
||||||
if (isset($context['associative'])) {
|
|
||||||
$options['associative'] = $context['associative'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($context['recursionDepth'])) {
|
|
||||||
$options['recursionDepth'] = $context['recursionDepth'];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (isset($context['options'])) {
|
|
||||||
$options['options'] = $context['options'];
|
|
||||||
}
|
|
||||||
|
|
||||||
return $options;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace Symfony\Component\Serializer\Encoder;
|
||||||
*
|
*
|
||||||
* @author Sander Coolen <sander@jibber.nl>
|
* @author Sander Coolen <sander@jibber.nl>
|
||||||
*/
|
*/
|
||||||
class JsonEncode extends SerializerAwareEncoder implements EncoderInterface
|
class JsonEncode implements EncoderInterface
|
||||||
{
|
{
|
||||||
private $options ;
|
private $options ;
|
||||||
private $lastError = JSON_ERROR_NONE;
|
private $lastError = JSON_ERROR_NONE;
|
||||||
|
@ -41,16 +41,13 @@ class JsonEncode extends SerializerAwareEncoder implements EncoderInterface
|
||||||
/**
|
/**
|
||||||
* Encodes PHP data to a JSON string
|
* Encodes PHP data to a JSON string
|
||||||
*
|
*
|
||||||
* @param mixed $data
|
* {@inheritdoc}
|
||||||
* @param string $format
|
|
||||||
*
|
|
||||||
* @return string
|
|
||||||
*/
|
*/
|
||||||
public function encode($data, $format)
|
public function encode($data, $format, array $context = array())
|
||||||
{
|
{
|
||||||
$options = $this->getContext();
|
$context = $this->resolveContext($context);
|
||||||
|
|
||||||
$encodedJson = json_encode($data, $options);
|
$encodedJson = json_encode($data, $context['json_encode_options']);
|
||||||
$this->lastError = json_last_error();
|
$this->lastError = json_last_error();
|
||||||
|
|
||||||
return $encodedJson;
|
return $encodedJson;
|
||||||
|
@ -64,22 +61,14 @@ class JsonEncode extends SerializerAwareEncoder implements EncoderInterface
|
||||||
return JsonEncoder::FORMAT === $format;
|
return JsonEncoder::FORMAT === $format;
|
||||||
}
|
}
|
||||||
|
|
||||||
private function getContext()
|
/**
|
||||||
|
* Merge default json encode options with context.
|
||||||
|
*
|
||||||
|
* @param array $context
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
private function resolveContext(array $context = array())
|
||||||
{
|
{
|
||||||
if (!$this->serializer) {
|
return array_merge(array('json_encode_options' => $this->options), $context);
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
$context = $this->serializer->getContext();
|
|
||||||
|
|
||||||
if (empty($context)) {
|
|
||||||
$context = array(0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!is_array($context)) {
|
|
||||||
$context = array($context);
|
|
||||||
}
|
|
||||||
|
|
||||||
return array_sum($context);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,7 +16,7 @@ namespace Symfony\Component\Serializer\Encoder;
|
||||||
*
|
*
|
||||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||||
*/
|
*/
|
||||||
class JsonEncoder extends SerializerAwareEncoder implements EncoderInterface, DecoderInterface
|
class JsonEncoder implements EncoderInterface, DecoderInterface
|
||||||
{
|
{
|
||||||
const FORMAT = 'json';
|
const FORMAT = 'json';
|
||||||
|
|
||||||
|
@ -59,21 +59,17 @@ class JsonEncoder extends SerializerAwareEncoder implements EncoderInterface, De
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function encode($data, $format)
|
public function encode($data, $format, array $context = array())
|
||||||
{
|
{
|
||||||
$this->encodingImpl->setSerializer($this->serializer);
|
return $this->encodingImpl->encode($data, self::FORMAT, $context);
|
||||||
|
|
||||||
return $this->encodingImpl->encode($data, self::FORMAT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function decode($data, $format)
|
public function decode($data, $format, array $context = array())
|
||||||
{
|
{
|
||||||
$this->decodingImpl->setSerializer($this->serializer);
|
return $this->decodingImpl->decode($data, self::FORMAT, $context);
|
||||||
|
|
||||||
return $this->decodingImpl->decode($data, self::FORMAT);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -26,24 +26,36 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
|
||||||
private $format;
|
private $format;
|
||||||
private $rootNodeName = 'response';
|
private $rootNodeName = 'response';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct new XmlEncoder and allow to change the root node element name.
|
||||||
|
*
|
||||||
|
* @param string $rootNodeName
|
||||||
|
*/
|
||||||
|
public function __construct($rootNodeName = 'response')
|
||||||
|
{
|
||||||
|
$this->rootNodeName = $rootNodeName;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function encode($data, $format)
|
public function encode($data, $format, array $context = array())
|
||||||
{
|
{
|
||||||
if ($data instanceof \DOMDocument) {
|
if ($data instanceof \DOMDocument) {
|
||||||
return $data->saveXML();
|
return $data->saveXML();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$xmlRootNodeName = $this->resolveXmlRootName($context);
|
||||||
|
|
||||||
$this->dom = new \DOMDocument();
|
$this->dom = new \DOMDocument();
|
||||||
$this->format = $format;
|
$this->format = $format;
|
||||||
|
|
||||||
if (null !== $data && !is_scalar($data)) {
|
if (null !== $data && !is_scalar($data)) {
|
||||||
$root = $this->dom->createElement($this->getRealRootNodeName());
|
$root = $this->dom->createElement($xmlRootNodeName);
|
||||||
$this->dom->appendChild($root);
|
$this->dom->appendChild($root);
|
||||||
$this->buildXml($root, $data);
|
$this->buildXml($root, $data, $xmlRootNodeName);
|
||||||
} else {
|
} else {
|
||||||
$this->appendNode($this->dom, $data, $this->getRealRootNodeName());
|
$this->appendNode($this->dom, $data, $xmlRootNodeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->dom->saveXML();
|
return $this->dom->saveXML();
|
||||||
|
@ -52,7 +64,7 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function decode($data, $format)
|
public function decode($data, $format, array $context = array())
|
||||||
{
|
{
|
||||||
$internalErrors = libxml_use_internal_errors(true);
|
$internalErrors = libxml_use_internal_errors(true);
|
||||||
$disableEntities = libxml_disable_entity_loader(true);
|
$disableEntities = libxml_disable_entity_loader(true);
|
||||||
|
@ -269,12 +281,13 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
|
||||||
*
|
*
|
||||||
* @param DOMNode $parentNode
|
* @param DOMNode $parentNode
|
||||||
* @param array|object $data data
|
* @param array|object $data data
|
||||||
|
* @param string $xmlRootNodeName
|
||||||
*
|
*
|
||||||
* @return Boolean
|
* @return Boolean
|
||||||
*
|
*
|
||||||
* @throws UnexpectedValueException
|
* @throws UnexpectedValueException
|
||||||
*/
|
*/
|
||||||
private function buildXml($parentNode, $data)
|
private function buildXml($parentNode, $data, $xmlRootNodeName)
|
||||||
{
|
{
|
||||||
$append = true;
|
$append = true;
|
||||||
|
|
||||||
|
@ -310,21 +323,24 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
|
||||||
|
|
||||||
return $append;
|
return $append;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (is_object($data)) {
|
if (is_object($data)) {
|
||||||
$data = $this->serializer->normalize($data, $this->format);
|
$data = $this->serializer->normalize($data, $this->format);
|
||||||
if (null !== $data && !is_scalar($data)) {
|
if (null !== $data && !is_scalar($data)) {
|
||||||
return $this->buildXml($parentNode, $data);
|
return $this->buildXml($parentNode, $data, $xmlRootNodeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
// top level data object was normalized into a scalar
|
// top level data object was normalized into a scalar
|
||||||
if (!$parentNode->parentNode->parentNode) {
|
if (!$parentNode->parentNode->parentNode) {
|
||||||
$root = $parentNode->parentNode;
|
$root = $parentNode->parentNode;
|
||||||
$root->removeChild($parentNode);
|
$root->removeChild($parentNode);
|
||||||
|
|
||||||
return $this->appendNode($root, $data, $this->getRealRootNodeName());
|
return $this->appendNode($root, $data, $xmlRootNodeName);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->appendNode($parentNode, $data, 'data');
|
return $this->appendNode($parentNode, $data, 'data');
|
||||||
}
|
}
|
||||||
|
|
||||||
throw new UnexpectedValueException('An unexpected value could not be serialized: '.var_export($data, true));
|
throw new UnexpectedValueException('An unexpected value could not be serialized: '.var_export($data, true));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -376,7 +392,7 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
|
||||||
private function selectNodeType($node, $val)
|
private function selectNodeType($node, $val)
|
||||||
{
|
{
|
||||||
if (is_array($val)) {
|
if (is_array($val)) {
|
||||||
return $this->buildXml($node, $val);
|
return $this->buildXml($node, $val, null);
|
||||||
} elseif ($val instanceof \SimpleXMLElement) {
|
} elseif ($val instanceof \SimpleXMLElement) {
|
||||||
$child = $this->dom->importNode(dom_import_simplexml($val), true);
|
$child = $this->dom->importNode(dom_import_simplexml($val), true);
|
||||||
$node->appendChild($child);
|
$node->appendChild($child);
|
||||||
|
@ -403,14 +419,8 @@ class XmlEncoder extends SerializerAwareEncoder implements EncoderInterface, Dec
|
||||||
/**
|
/**
|
||||||
* Get real XML root node name, taking serializer options into account.
|
* Get real XML root node name, taking serializer options into account.
|
||||||
*/
|
*/
|
||||||
private function getRealRootNodeName()
|
private function resolveXmlRootName(array $context = array())
|
||||||
{
|
{
|
||||||
if (!$this->serializer) {
|
|
||||||
return $this->rootNodeName;
|
|
||||||
}
|
|
||||||
|
|
||||||
$context = $this->serializer->getContext();
|
|
||||||
|
|
||||||
return isset($context['xml_root_node_name'])
|
return isset($context['xml_root_node_name'])
|
||||||
? $context['xml_root_node_name']
|
? $context['xml_root_node_name']
|
||||||
: $this->rootNodeName;
|
: $this->rootNodeName;
|
||||||
|
|
|
@ -19,18 +19,18 @@ class CustomNormalizer extends SerializerAwareNormalizer implements NormalizerIn
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function normalize($object, $format = null)
|
public function normalize($object, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
return $object->normalize($this->serializer, $format);
|
return $object->normalize($this->serializer, $format, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function denormalize($data, $class, $format = null)
|
public function denormalize($data, $class, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
$object = new $class;
|
$object = new $class;
|
||||||
$object->denormalize($this->serializer, $data, $format);
|
$object->denormalize($this->serializer, $data, $format, $context);
|
||||||
|
|
||||||
return $object;
|
return $object;
|
||||||
}
|
}
|
||||||
|
|
|
@ -32,6 +32,7 @@ interface DenormalizableInterface
|
||||||
* @param array|scalar $data The data from which to re-create the object.
|
* @param array|scalar $data The data from which to re-create the object.
|
||||||
* @param string|null $format The format is optionally given to be able to denormalize differently
|
* @param string|null $format The format is optionally given to be able to denormalize differently
|
||||||
* based on different input formats.
|
* based on different input formats.
|
||||||
|
* @param array $context options for denormalizing
|
||||||
*/
|
*/
|
||||||
public function denormalize(DenormalizerInterface $denormalizer, $data, $format = null);
|
public function denormalize(DenormalizerInterface $denormalizer, $data, $format = null, array $context = array());
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,10 +24,11 @@ interface DenormalizerInterface
|
||||||
* @param mixed $data data to restore
|
* @param mixed $data data to restore
|
||||||
* @param string $class the expected class to instantiate
|
* @param string $class the expected class to instantiate
|
||||||
* @param string $format format the given data was extracted from
|
* @param string $format format the given data was extracted from
|
||||||
|
* @param array $context options available to the denormalizer
|
||||||
*
|
*
|
||||||
* @return object
|
* @return object
|
||||||
*/
|
*/
|
||||||
public function denormalize($data, $class, $format = null);
|
public function denormalize($data, $class, $format = null, array $context = array());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the given class is supported for denormalization by this normalizer
|
* Checks whether the given class is supported for denormalization by this normalizer
|
||||||
|
|
|
@ -69,7 +69,7 @@ class GetSetMethodNormalizer extends SerializerAwareNormalizer implements Normal
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function normalize($object, $format = null)
|
public function normalize($object, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
$reflectionObject = new \ReflectionObject($object);
|
$reflectionObject = new \ReflectionObject($object);
|
||||||
$reflectionMethods = $reflectionObject->getMethods(\ReflectionMethod::IS_PUBLIC);
|
$reflectionMethods = $reflectionObject->getMethods(\ReflectionMethod::IS_PUBLIC);
|
||||||
|
@ -101,7 +101,7 @@ class GetSetMethodNormalizer extends SerializerAwareNormalizer implements Normal
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function denormalize($data, $class, $format = null)
|
public function denormalize($data, $class, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
$reflectionClass = new \ReflectionClass($class);
|
$reflectionClass = new \ReflectionClass($class);
|
||||||
$constructor = $reflectionClass->getConstructor();
|
$constructor = $reflectionClass->getConstructor();
|
||||||
|
|
|
@ -31,8 +31,9 @@ interface NormalizableInterface
|
||||||
* can use it to normalize objects contained within this object.
|
* can use it to normalize objects contained within this object.
|
||||||
* @param string|null $format The format is optionally given to be able to normalize differently
|
* @param string|null $format The format is optionally given to be able to normalize differently
|
||||||
* based on different output formats.
|
* based on different output formats.
|
||||||
|
* @param array $context Options for normalizing this object
|
||||||
*
|
*
|
||||||
* @return array|scalar
|
* @return array|scalar
|
||||||
*/
|
*/
|
||||||
public function normalize(NormalizerInterface $normalizer, $format = null);
|
public function normalize(NormalizerInterface $normalizer, $format = null, array $context = array());
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,10 +23,11 @@ interface NormalizerInterface
|
||||||
*
|
*
|
||||||
* @param object $object object to normalize
|
* @param object $object object to normalize
|
||||||
* @param string $format format the normalization result will be encoded as
|
* @param string $format format the normalization result will be encoded as
|
||||||
|
* @param array $context Context options for the normalizer
|
||||||
*
|
*
|
||||||
* @return array|scalar
|
* @return array|scalar
|
||||||
*/
|
*/
|
||||||
public function normalize($object, $format = null);
|
public function normalize($object, $format = null, array $context = array());
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the given class is supported for normalization by this normalizer
|
* Checks whether the given class is supported for normalization by this normalizer
|
||||||
|
|
|
@ -42,7 +42,6 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
|
||||||
protected $normalizers = array();
|
protected $normalizers = array();
|
||||||
protected $normalizerCache = array();
|
protected $normalizerCache = array();
|
||||||
protected $denormalizerCache = array();
|
protected $denormalizerCache = array();
|
||||||
protected $context;
|
|
||||||
|
|
||||||
public function __construct(array $normalizers = array(), array $encoders = array())
|
public function __construct(array $normalizers = array(), array $encoders = array())
|
||||||
{
|
{
|
||||||
|
@ -79,13 +78,11 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
|
||||||
throw new UnexpectedValueException('Serialization for the format '.$format.' is not supported');
|
throw new UnexpectedValueException('Serialization for the format '.$format.' is not supported');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->context = $context;
|
|
||||||
|
|
||||||
if ($this->encoder->needsNormalization($format)) {
|
if ($this->encoder->needsNormalization($format)) {
|
||||||
$data = $this->normalize($data, $format);
|
$data = $this->normalize($data, $format, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $this->encode($data, $format);
|
return $this->encode($data, $format, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -97,38 +94,36 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
|
||||||
throw new UnexpectedValueException('Deserialization for the format '.$format.' is not supported');
|
throw new UnexpectedValueException('Deserialization for the format '.$format.' is not supported');
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->context = $context;
|
$data = $this->decode($data, $format, $context);
|
||||||
|
|
||||||
$data = $this->decode($data, $format);
|
return $this->denormalize($data, $type, $format, $context);
|
||||||
|
|
||||||
return $this->denormalize($data, $type, $format);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function normalize($data, $format = null)
|
public function normalize($data, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
if (null === $data || is_scalar($data)) {
|
if (null === $data || is_scalar($data)) {
|
||||||
return $data;
|
return $data;
|
||||||
}
|
}
|
||||||
if (is_object($data) && $this->supportsNormalization($data, $format)) {
|
if (is_object($data) && $this->supportsNormalization($data, $format)) {
|
||||||
return $this->normalizeObject($data, $format);
|
return $this->normalizeObject($data, $format, $context);
|
||||||
}
|
}
|
||||||
if ($data instanceof \Traversable) {
|
if ($data instanceof \Traversable) {
|
||||||
$normalized = array();
|
$normalized = array();
|
||||||
foreach ($data as $key => $val) {
|
foreach ($data as $key => $val) {
|
||||||
$normalized[$key] = $this->normalize($val, $format);
|
$normalized[$key] = $this->normalize($val, $format, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $normalized;
|
return $normalized;
|
||||||
}
|
}
|
||||||
if (is_object($data)) {
|
if (is_object($data)) {
|
||||||
return $this->normalizeObject($data, $format);
|
return $this->normalizeObject($data, $format, $context);
|
||||||
}
|
}
|
||||||
if (is_array($data)) {
|
if (is_array($data)) {
|
||||||
foreach ($data as $key => $val) {
|
foreach ($data as $key => $val) {
|
||||||
$data[$key] = $this->normalize($val, $format);
|
$data[$key] = $this->normalize($val, $format, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
return $data;
|
return $data;
|
||||||
|
@ -139,9 +134,9 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
public function denormalize($data, $type, $format = null)
|
public function denormalize($data, $type, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
return $this->denormalizeObject($data, $type, $format);
|
return $this->denormalizeObject($data, $type, $format, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -207,17 +202,17 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
final public function encode($data, $format)
|
final public function encode($data, $format, array $context = array())
|
||||||
{
|
{
|
||||||
return $this->encoder->encode($data, $format);
|
return $this->encoder->encode($data, $format, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@inheritdoc}
|
* {@inheritdoc}
|
||||||
*/
|
*/
|
||||||
final public function decode($data, $format)
|
final public function decode($data, $format, array $context = array())
|
||||||
{
|
{
|
||||||
return $this->decoder->decode($data, $format);
|
return $this->decoder->decode($data, $format, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -225,13 +220,14 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
|
||||||
*
|
*
|
||||||
* @param object $object object to normalize
|
* @param object $object object to normalize
|
||||||
* @param string $format format name, present to give the option to normalizers to act differently based on formats
|
* @param string $format format name, present to give the option to normalizers to act differently based on formats
|
||||||
|
* @param array $context The context data for this particular normalization
|
||||||
*
|
*
|
||||||
* @return array|scalar
|
* @return array|scalar
|
||||||
*
|
*
|
||||||
* @throws LogicException
|
* @throws LogicException
|
||||||
* @throws UnexpectedValueException
|
* @throws UnexpectedValueException
|
||||||
*/
|
*/
|
||||||
private function normalizeObject($object, $format = null)
|
private function normalizeObject($object, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
if (!$this->normalizers) {
|
if (!$this->normalizers) {
|
||||||
throw new LogicException('You must register at least one normalizer to be able to normalize objects.');
|
throw new LogicException('You must register at least one normalizer to be able to normalize objects.');
|
||||||
|
@ -239,14 +235,14 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
|
||||||
|
|
||||||
$class = get_class($object);
|
$class = get_class($object);
|
||||||
if (isset($this->normalizerCache[$class][$format])) {
|
if (isset($this->normalizerCache[$class][$format])) {
|
||||||
return $this->normalizerCache[$class][$format]->normalize($object, $format);
|
return $this->normalizerCache[$class][$format]->normalize($object, $format, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->normalizers as $normalizer) {
|
foreach ($this->normalizers as $normalizer) {
|
||||||
if ($normalizer->supportsNormalization($object, $format)) {
|
if ($normalizer->supportsNormalization($object, $format)) {
|
||||||
$this->normalizerCache[$class][$format] = $normalizer;
|
$this->normalizerCache[$class][$format] = $normalizer;
|
||||||
|
|
||||||
return $normalizer->normalize($object, $format);
|
return $normalizer->normalize($object, $format, $context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -259,27 +255,28 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
|
||||||
* @param mixed $data data to restore
|
* @param mixed $data data to restore
|
||||||
* @param string $class the expected class to instantiate
|
* @param string $class the expected class to instantiate
|
||||||
* @param string $format format name, present to give the option to normalizers to act differently based on formats
|
* @param string $format format name, present to give the option to normalizers to act differently based on formats
|
||||||
|
* @param array $context The context data for this particular denormalization
|
||||||
*
|
*
|
||||||
* @return object
|
* @return object
|
||||||
*
|
*
|
||||||
* @throws LogicException
|
* @throws LogicException
|
||||||
* @throws UnexpectedValueException
|
* @throws UnexpectedValueException
|
||||||
*/
|
*/
|
||||||
private function denormalizeObject($data, $class, $format = null)
|
private function denormalizeObject($data, $class, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
if (!$this->normalizers) {
|
if (!$this->normalizers) {
|
||||||
throw new LogicException('You must register at least one normalizer to be able to denormalize objects.');
|
throw new LogicException('You must register at least one normalizer to be able to denormalize objects.');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isset($this->denormalizerCache[$class][$format])) {
|
if (isset($this->denormalizerCache[$class][$format])) {
|
||||||
return $this->denormalizerCache[$class][$format]->denormalize($data, $class, $format);
|
return $this->denormalizerCache[$class][$format]->denormalize($data, $class, $format, $context);
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach ($this->normalizers as $normalizer) {
|
foreach ($this->normalizers as $normalizer) {
|
||||||
if ($normalizer->supportsDenormalization($data, $class, $format)) {
|
if ($normalizer->supportsDenormalization($data, $class, $format)) {
|
||||||
$this->denormalizerCache[$class][$format] = $normalizer;
|
$this->denormalizerCache[$class][$format] = $normalizer;
|
||||||
|
|
||||||
return $normalizer->denormalize($data, $class, $format);
|
return $normalizer->denormalize($data, $class, $format, $context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -301,12 +298,4 @@ class Serializer implements SerializerInterface, NormalizerInterface, Denormaliz
|
||||||
{
|
{
|
||||||
return $this->decoder->supportsDecoding($format);
|
return $this->decoder->supportsDecoding($format);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@inheritdoc}
|
|
||||||
*/
|
|
||||||
public function getContext()
|
|
||||||
{
|
|
||||||
return $this->context;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -40,11 +40,4 @@ interface SerializerInterface
|
||||||
* @return object
|
* @return object
|
||||||
*/
|
*/
|
||||||
public function deserialize($data, $type, $format, array $context = array());
|
public function deserialize($data, $type, $format, array $context = array());
|
||||||
|
|
||||||
/**
|
|
||||||
* Get current options of the serializer
|
|
||||||
*
|
|
||||||
* @return array
|
|
||||||
*/
|
|
||||||
public function getContext();
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,7 +21,6 @@ class JsonEncoderTest extends \PHPUnit_Framework_TestCase
|
||||||
{
|
{
|
||||||
$this->encoder = new JsonEncoder;
|
$this->encoder = new JsonEncoder;
|
||||||
$this->serializer = new Serializer(array(new CustomNormalizer()), array('json' => new JsonEncoder()));
|
$this->serializer = new Serializer(array(new CustomNormalizer()), array('json' => new JsonEncoder()));
|
||||||
$this->encoder->setSerializer($this->serializer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public function testEncodeScalar()
|
public function testEncodeScalar()
|
||||||
|
@ -45,7 +44,7 @@ class JsonEncoderTest extends \PHPUnit_Framework_TestCase
|
||||||
|
|
||||||
public function testOptions()
|
public function testOptions()
|
||||||
{
|
{
|
||||||
$context = array(JSON_NUMERIC_CHECK);
|
$context = array('json_encode_options' => JSON_NUMERIC_CHECK);
|
||||||
|
|
||||||
$arr = array();
|
$arr = array();
|
||||||
$arr['foo'] = "3";
|
$arr['foo'] = "3";
|
||||||
|
|
|
@ -17,7 +17,7 @@ use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||||
class DenormalizableDummy implements DenormalizableInterface
|
class DenormalizableDummy implements DenormalizableInterface
|
||||||
{
|
{
|
||||||
|
|
||||||
public function denormalize(DenormalizerInterface $denormalizer, $data, $format = null)
|
public function denormalize(DenormalizerInterface $denormalizer, $data, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,7 +23,7 @@ class Dummy implements NormalizableInterface, DenormalizableInterface
|
||||||
public $baz;
|
public $baz;
|
||||||
public $qux;
|
public $qux;
|
||||||
|
|
||||||
public function normalize(NormalizerInterface $normalizer, $format = null)
|
public function normalize(NormalizerInterface $normalizer, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'foo' => $this->foo,
|
'foo' => $this->foo,
|
||||||
|
@ -33,7 +33,7 @@ class Dummy implements NormalizableInterface, DenormalizableInterface
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function denormalize(DenormalizerInterface $denormalizer, $data, $format = null)
|
public function denormalize(DenormalizerInterface $denormalizer, $data, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
$this->foo = $data['foo'];
|
$this->foo = $data['foo'];
|
||||||
$this->bar = $data['bar'];
|
$this->bar = $data['bar'];
|
||||||
|
|
|
@ -18,7 +18,7 @@ use Symfony\Component\Serializer\Normalizer\DenormalizerInterface;
|
||||||
|
|
||||||
class NormalizableTraversableDummy extends TraversableDummy implements NormalizableInterface, DenormalizableInterface
|
class NormalizableTraversableDummy extends TraversableDummy implements NormalizableInterface, DenormalizableInterface
|
||||||
{
|
{
|
||||||
public function normalize(NormalizerInterface $normalizer, $format = null)
|
public function normalize(NormalizerInterface $normalizer, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'foo' => 'normalizedFoo',
|
'foo' => 'normalizedFoo',
|
||||||
|
@ -26,7 +26,7 @@ class NormalizableTraversableDummy extends TraversableDummy implements Normaliza
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public function denormalize(DenormalizerInterface $denormalizer, $data, $format = null)
|
public function denormalize(DenormalizerInterface $denormalizer, $data, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
return array(
|
return array(
|
||||||
'foo' => 'denormalizedFoo',
|
'foo' => 'denormalizedFoo',
|
||||||
|
|
|
@ -21,12 +21,12 @@ class ScalarDummy implements NormalizableInterface, DenormalizableInterface
|
||||||
public $foo;
|
public $foo;
|
||||||
public $xmlFoo;
|
public $xmlFoo;
|
||||||
|
|
||||||
public function normalize(NormalizerInterface $normalizer, $format = null)
|
public function normalize(NormalizerInterface $normalizer, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
return $format === 'xml' ? $this->xmlFoo : $this->foo;
|
return $format === 'xml' ? $this->xmlFoo : $this->foo;
|
||||||
}
|
}
|
||||||
|
|
||||||
public function denormalize(DenormalizerInterface $denormalizer, $data, $format = null)
|
public function denormalize(DenormalizerInterface $denormalizer, $data, $format = null, array $context = array())
|
||||||
{
|
{
|
||||||
if ($format === 'xml') {
|
if ($format === 'xml') {
|
||||||
$this->xmlFoo = $data;
|
$this->xmlFoo = $data;
|
||||||
|
|
Reference in New Issue