Commit 80152b7d authored by alexpott's avatar alexpott

Issue #2310527 by damiankloip: Upgrade Serializer component to 2.5.2.

parent d1ba2473
......@@ -143,6 +143,8 @@ public function add($prefix, $paths, $prepend = false)
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-0 base directories
* @param bool $prepend Whether to prepend the directories
*
* @throws \InvalidArgumentException
*/
public function addPsr4($prefix, $paths, $prepend = false)
{
......@@ -204,6 +206,8 @@ public function set($prefix, $paths)
*
* @param string $prefix The prefix/namespace, with trailing '\\'
* @param array|string $paths The PSR-4 base directories
*
* @throws \InvalidArgumentException
*/
public function setPsr4($prefix, $paths)
{
......
......@@ -1336,55 +1336,6 @@
"url"
]
},
{
"name": "symfony/serializer",
"version": "v2.4.1",
"version_normalized": "2.4.1.0",
"target-dir": "Symfony/Component/Serializer",
"source": {
"type": "git",
"url": "https://github.com/symfony/Serializer.git",
"reference": "60c54346958604379392672a3a998650a169a7f4"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Serializer/zipball/60c54346958604379392672a3a998650a169a7f4",
"reference": "60c54346958604379392672a3a998650a169a7f4",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"time": "2014-01-01 08:14:50",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.4-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\Serializer\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Serializer Component",
"homepage": "http://symfony.com"
},
{
"name": "symfony/property-access",
"version": "v2.4.1",
......@@ -2502,5 +2453,56 @@
"BSD"
],
"homepage": "http://vfs.bovigo.org/"
},
{
"name": "symfony/serializer",
"version": "v2.5.2",
"version_normalized": "2.5.2.0",
"target-dir": "Symfony/Component/Serializer",
"source": {
"type": "git",
"url": "https://github.com/symfony/Serializer.git",
"reference": "33185b290310ab1fd8283fb8ed2a434cdb88b9b9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/symfony/Serializer/zipball/33185b290310ab1fd8283fb8ed2a434cdb88b9b9",
"reference": "33185b290310ab1fd8283fb8ed2a434cdb88b9b9",
"shasum": ""
},
"require": {
"php": ">=5.3.3"
},
"time": "2014-07-09 09:05:48",
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "2.5-dev"
}
},
"installation-source": "dist",
"autoload": {
"psr-0": {
"Symfony\\Component\\Serializer\\": ""
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Fabien Potencier",
"email": "fabien@symfony.com",
"homepage": "http://fabien.potencier.org",
"role": "Lead Developer"
},
{
"name": "Symfony Community",
"homepage": "http://symfony.com/contributors"
}
],
"description": "Symfony Serializer Component",
"homepage": "http://symfony.com"
}
]
CHANGELOG
=========
2.5.0
-----
* added support for `is.*` getters in `GetSetMethodNormalizer`
2.4.0
-----
* added `$context` support for XMLEncoder.
* [DEPRECATION] JsonEncode and JsonDecode where modified to throw
an exception if error found. No need for get*Error() functions
2.3.0
-----
......
......@@ -57,7 +57,7 @@ public function supportsEncoding($format)
*
* @param string $format
*
* @return Boolean
* @return bool
*/
public function needsNormalization($format)
{
......
......@@ -11,6 +11,8 @@
namespace Symfony\Component\Serializer\Encoder;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
/**
* Defines the interface of decoders
*
......@@ -31,6 +33,8 @@ interface DecoderInterface
* phpdoc comment.
*
* @return mixed
*
* @throws UnexpectedValueException
*/
public function decode($data, $format, array $context = array());
......@@ -39,7 +43,7 @@ public function decode($data, $format, array $context = array());
*
* @param string $format format name
*
* @return Boolean
* @return bool
*/
public function supportsDecoding($format);
}
......@@ -11,6 +11,8 @@
namespace Symfony\Component\Serializer\Encoder;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
/**
* Defines the interface of encoders
*
......@@ -26,6 +28,8 @@ interface EncoderInterface
* @param array $context options that normalizers/encoders have access to.
*
* @return scalar
*
* @throws UnexpectedValueException
*/
public function encode($data, $format, array $context = array());
......@@ -34,7 +38,7 @@ public function encode($data, $format, array $context = array());
*
* @param string $format format name
*
* @return Boolean
* @return bool
*/
public function supportsEncoding($format);
}
......@@ -11,6 +11,8 @@
namespace Symfony\Component\Serializer\Encoder;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
/**
* Decodes JSON data
*
......@@ -21,25 +23,26 @@ class JsonDecode implements DecoderInterface
/**
* Specifies if the returned result should be an associative array or a nested stdClass object hierarchy.
*
* @var Boolean
* @var bool
*/
private $associative;
/**
* Specifies the recursion depth.
*
* @var integer
* @var int
*/
private $recursionDepth;
private $lastError = JSON_ERROR_NONE;
protected $serializer;
/**
* Constructs a new JsonDecode instance.
*
* @param Boolean $associative True to return the result associative array, false for a nested stdClass hierarchy
* @param integer $depth Specifies the recursion depth
* @param bool $associative True to return the result associative array, false for a nested stdClass hierarchy
* @param int $depth Specifies the recursion depth
*/
public function __construct($associative = false, $depth = 512)
{
......@@ -50,7 +53,9 @@ public function __construct($associative = false, $depth = 512)
/**
* Returns the last decoding error (if any).
*
* @return integer
* @return int
*
* @deprecated since 2.5, decode() throws an exception if error found, will be removed in 3.0
*
* @see http://php.net/manual/en/function.json-last-error.php json_last_error
*/
......@@ -82,6 +87,8 @@ public function getLastError()
*
* @return mixed
*
* @throws UnexpectedValueException
*
* @see http://php.net/json_decode json_decode
*/
public function decode($data, $format, array $context = array())
......@@ -98,7 +105,9 @@ public function decode($data, $format, array $context = array())
$decodedData = json_decode($data, $associative, $recursionDepth);
}
$this->lastError = json_last_error();
if (JSON_ERROR_NONE !== $this->lastError = json_last_error()) {
throw new UnexpectedValueException(JsonEncoder::getLastErrorMessage());
}
return $decodedData;
}
......
......@@ -11,6 +11,8 @@
namespace Symfony\Component\Serializer\Encoder;
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
/**
* Encodes JSON data
*
......@@ -27,9 +29,11 @@ public function __construct($bitmask = 0)
}
/**
* Returns the last encoding error (if any)
* Returns the last encoding error (if any).
*
* @return int
*
* @return integer
* @deprecated since 2.5, encode() throws an exception if error found, will be removed in 3.0
*
* @see http://php.net/manual/en/function.json-last-error.php json_last_error
*/
......@@ -48,7 +52,10 @@ public function encode($data, $format, array $context = array())
$context = $this->resolveContext($context);
$encodedJson = json_encode($data, $context['json_encode_options']);
$this->lastError = json_last_error();
if (JSON_ERROR_NONE !== $this->lastError = json_last_error()) {
throw new UnexpectedValueException(JsonEncoder::getLastErrorMessage());
}
return $encodedJson;
}
......
......@@ -39,7 +39,9 @@ public function __construct(JsonEncode $encodingImpl = null, JsonDecode $decodin
/**
* Returns the last encoding error (if any)
*
* @return integer
* @return int
*
* @deprecated since 2.5, JsonEncode throws exception if an error is found, will be removed in 3.0
*/
public function getLastEncodingError()
{
......@@ -49,7 +51,9 @@ public function getLastEncodingError()
/**
* Returns the last decoding error (if any)
*
* @return integer
* @return int
*
* @deprecated since 2.5, JsonDecode throws exception if an error is found, will be removed in 3.0
*/
public function getLastDecodingError()
{
......@@ -87,4 +91,31 @@ public function supportsDecoding($format)
{
return self::FORMAT === $format;
}
/**
* Resolves json_last_error message.
*
* @return string
*/
public static function getLastErrorMessage()
{
if (function_exists('json_last_error_msg')) {
return json_last_error_msg();
}
switch (json_last_error()) {
case JSON_ERROR_DEPTH:
return 'Maximum stack depth exceeded';
case JSON_ERROR_STATE_MISMATCH:
return 'Underflow or the modes mismatch';
case JSON_ERROR_CTRL_CHAR:
return 'Unexpected control character found';
case JSON_ERROR_SYNTAX:
return 'Syntax error, malformed JSON';
case JSON_ERROR_UTF8:
return 'Malformed UTF-8 characters, possibly incorrectly encoded';
default:
return 'Unknown error';
}
}
}
......@@ -68,17 +68,23 @@ public function encode($data, $format, array $context = array())
*/
public function decode($data, $format, array $context = array())
{
if ('' === trim($data)) {
throw new UnexpectedValueException('Invalid XML data, it can not be empty.');
}
$internalErrors = libxml_use_internal_errors(true);
$disableEntities = libxml_disable_entity_loader(true);
libxml_clear_errors();
$dom = new \DOMDocument();
$dom->loadXML($data, LIBXML_NONET);
$dom->loadXML($data, LIBXML_NONET | LIBXML_NOBLANKS);
libxml_use_internal_errors($internalErrors);
libxml_disable_entity_loader($disableEntities);
if ($error = libxml_get_last_error()) {
libxml_clear_errors();
throw new UnexpectedValueException($error->message);
}
......@@ -88,26 +94,27 @@ public function decode($data, $format, array $context = array())
}
}
$xml = simplexml_import_dom($dom);
$rootNode = $dom->firstChild;
if ($error = libxml_get_last_error()) {
throw new UnexpectedValueException($error->message);
// todo: throw an exception if the root node name is not correctly configured (bc)
if ($rootNode->hasChildNodes()) {
return $this->parseXml($rootNode);
}
if (!$xml->count()) {
if (!$xml->attributes()) {
return (string) $xml;
}
$data = array();
foreach ($xml->attributes() as $attrkey => $attr) {
$data['@'.$attrkey] = (string) $attr;
}
$data['#'] = (string) $xml;
if (!$rootNode->hasAttributes()) {
return $rootNode->nodeValue;
}
return $data;
$data = array();
foreach ($rootNode->attributes as $attrKey => $attr) {
$data['@'.$attrKey] = $attr->nodeValue;
}
return $this->parseXml($xml);
$data['#'] = $rootNode->nodeValue;
return $data;
}
/**
......@@ -149,7 +156,7 @@ public function getRootNodeName()
* @param \DOMNode $node
* @param string $val
*
* @return Boolean
* @return bool
*/
final protected function appendXMLString(\DOMNode $node, $val)
{
......@@ -168,7 +175,7 @@ public function getRootNodeName()
* @param \DOMNode $node
* @param string $val
*
* @return Boolean
* @return bool
*/
final protected function appendText(\DOMNode $node, $val)
{
......@@ -182,7 +189,7 @@ public function getRootNodeName()
* @param \DOMNode $node
* @param string $val
*
* @return Boolean
* @return bool
*/
final protected function appendCData(\DOMNode $node, $val)
{
......@@ -196,7 +203,7 @@ public function getRootNodeName()
* @param \DOMNode $node
* @param \DOMDocumentFragment $fragment
*
* @return Boolean
* @return bool
*/
final protected function appendDocumentFragment(\DOMNode $node, $fragment)
{
......@@ -214,7 +221,7 @@ public function getRootNodeName()
*
* @param string $name
*
* @return Boolean
* @return bool
*/
final protected function isElementNameValid($name)
{
......@@ -224,54 +231,107 @@ public function getRootNodeName()
}
/**
* Parse the input SimpleXmlElement into an array.
* Parse the input DOMNode into an array or a string.
*
* @param \DOMNode $node xml to parse
*
* @return array|string
*/
private function parseXml(\DOMNode $node)
{
$data = $this->parseXmlAttributes($node);
$value = $this->parseXmlValue($node);
if (!count($data)) {
return $value;
}
if (!is_array($value)) {
$data['#'] = $value;
return $data;
}
if (1 === count($value) && key($value)) {
$data[key($value)] = current($value);
return $data;
}
foreach ($value as $key => $val) {
$data[$key] = $val;
}
return $data;
}
/**
* Parse the input DOMNode attributes into an array
*
* @param \SimpleXmlElement $node xml to parse
* @param \DOMNode $node xml to parse
*
* @return array
*/
private function parseXml(\SimpleXmlElement $node)
private function parseXmlAttributes(\DOMNode $node)
{
$data = array();
if ($node->attributes()) {
foreach ($node->attributes() as $attrkey => $attr) {
$data['@'.$attrkey] = (string) $attr;
}
if (!$node->hasAttributes()) {
return array();
}
foreach ($node->children() as $key => $subnode) {
if ($subnode->count()) {
$value = $this->parseXml($subnode);
} elseif ($subnode->attributes()) {
$value = array();
foreach ($subnode->attributes() as $attrkey => $attr) {
$value['@'.$attrkey] = (string) $attr;
}
$value['#'] = (string) $subnode;
$data = array();
foreach ($node->attributes as $attrkey => $attr) {
if (ctype_digit($attr->nodeValue)) {
$data['@'.$attrkey] = (int) $attr->nodeValue;
} else {
$value = (string) $subnode;
$data['@'.$attrkey] = $attr->nodeValue;
}
}
if ($key === 'item') {
if (isset($value['@key'])) {
if (isset($value['#'])) {
$data[$value['@key']] = $value['#'];
} else {
$data[$value['@key']] = $value;
}
return $data;
}
/**
* Parse the input DOMNode value (content and children) into an array or a string
*
* @param \DOMNode $node xml to parse
*
* @return array|string
*/
private function parseXmlValue(\DOMNode $node)
{
if (!$node->hasChildNodes()) {
return $node->nodeValue;
}
if (1 === $node->childNodes->length && in_array($node->firstChild->nodeType, array(XML_TEXT_NODE, XML_CDATA_SECTION_NODE))) {
return $node->firstChild->nodeValue;
}
$value = array();
foreach ($node->childNodes as $subnode) {
$val = $this->parseXml($subnode);
if ('item' === $subnode->nodeName && isset($val['@key'])) {
if (isset($val['#'])) {
$value[$val['@key']] = $val['#'];
} else {
$data['item'][] = $value;
}
} elseif (array_key_exists($key, $data) || $key == "entry") {
if ((false === is_array($data[$key])) || (false === isset($data[$key][0]))) {
$data[$key] = array($data[$key]);
$value[$val['@key']] = $val;
}
$data[$key][] = $value;
} else {
$data[$key] = $value;
$value[$subnode->nodeName][] = $val;
}
}
return $data;
foreach ($value as $key => $val) {
if (is_array($val) && 1 === count($val)) {
$value[$key] = current($val);
}
}
return $value;
}
/**
......@@ -281,7 +341,7 @@ private function parseXml(\SimpleXmlElement $node)
* @param array|object $data
* @param string|null $xmlRootNodeName
*
* @return Boolean
* @return bool
*
* @throws UnexpectedValueException
*/
......@@ -350,7 +410,7 @@ private function buildXml(\DOMNode $parentNode, $data, $xmlRootNodeName = null)
* @param string $nodeName
* @param string $key
*
* @return Boolean
* @return bool
*/
private function appendNode(\DOMNode $parentNode, $data, $nodeName, $key = null)
{
......@@ -372,7 +432,7 @@ private function appendNode(\DOMNode $parentNode, $data, $nodeName, $key = null)
*
* @param string $val
*
* @return Boolean
* @return bool
*/
private function needsCdataWrapping($val)
{
......@@ -385,7 +445,7 @@ private function needsCdataWrapping($val)
* @param \DOMNode $node
* @param mixed $val
*
* @return Boolean
* @return bool
*/
private function selectNodeType(\DOMNode $node, $val)
{
......