8000 [Serializer] Xml encoder throws exception for valid data · symfony/symfony@5c2d4c6 · GitHub
[go: up one dir, main page]

Skip to content

Commit 5c2d4c6

Browse files
gr1ev0usfabpot
authored andcommitted
[Serializer] Xml encoder throws exception for valid data
1 parent 00c61da commit 5c2d4c6

File tree

2 files changed

+96
-2
lines changed

2 files changed

+96
-2
lines changed

src/Symfony/Component/Serializer/Encoder/XmlEncoder.php

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -369,7 +369,10 @@ private function buildXml(\DOMNode $parentNode, $data, $xmlRootNodeName = null)
369369
if (is_array($data) || ($data instanceof \Traversable && !$this->serializer->supportsNormalization($data, $this->format))) {
370370
foreach ($data as $key => $data) {
371371
//Ah this is the magic @ attribute types.
372-
if (0 === strpos($key, '@') && is_scalar($data) && $this->isElementNameValid($attributeName = substr($key, 1))) {
372+
if (0 === strpos($key, '@') && $this->isElementNameValid($attributeName = substr($key, 1))) {
373+
if (!is_scalar($data)) {
374+
$data = $this->serializer->normalize($data, $this->format, $this->context);
375+
}
373376
$parentNode->setAttribute($attributeName, $data);
374377
} elseif ($key === '#') {
375378
$append = $this->selectNodeType($parentNode, $data);
@@ -474,7 +477,7 @@ private function selectNodeType(\DOMNode $node, $val)
474477
} elseif ($val instanceof \Traversable) {
475478
$this->buildXml($node, $val);
476479
} elseif (is_object($val)) {
477-
return $this->buildXml($node, $this->serializer->normalize($val, $this->format, $this->context));
480+
return $this->selectNodeType($node, $this->serializer->normalize($val, $this->format, $this->context));
478481
} elseif (is_numeric($val)) {
479482
return $this->appendText($node, (string) $val);
480483
} elseif (is_string($val) && $this->needsCdataWrapping($val)) {

src/Symfony/Component/Serializer/Tests/Encoder/XmlEncoderTest.php

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,17 @@
1919
use Symfony\Component\Serializer\Serializer;
2020
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
2121
use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
22+
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
2223

2324
class XmlEncoderTest extends TestCase
2425
{
26+
/**
27+
* @var XmlEncoder
28+
*/
2529
private $encoder;
2630

31+
private $exampleDateTimeString = '2017-02-19T15:16:08+0300';
32+
2733
protected function setUp()
2834
{
2935
$this->encoder = new XmlEncoder();
@@ -524,4 +530,89 @@ protected function getObject()
524530

525531
return $obj;
526532
}
533+
534+
public function testEncodeXmlWithBoolValue()
535+
{
536+
$expectedXml = <<<'XML'
537+
<?xml version="1.0"?>
538+
<response><foo>1</foo><bar>0</bar></response>
539+
540+
XML;
541+
542+
$actualXml = $this->encoder->encode(array('foo' => true, 'bar' => false), 'xml');
543+
544+
$this->assertEquals($expectedXml, $actualXml);
545+
}
546+
547+
public function testEncodeXmlWithDateTimeObjectValue()
548+
{
549+
$xmlEncoder = $this->createXmlEncoderWithDateTimeNormalizer();
550+
551+
$actualXml = $xmlEncoder->encode(array('dateTime' => new \DateTime($this->exampleDateTimeString)), 'xml');
552+
553+
$this->assertEquals($this->createXmlWithDateTime(), $actualXml);
554+
}
555+
556+
public function testEncodeXmlWithDateTimeObjectField()
557+
{
558+
$xmlEncoder = $this->createXmlEncoderWithDateTimeNormalizer();
559+
560+
$actualXml = $xmlEncoder->encode(array('foo' => array('@dateTime' => new \DateTime($this->exampleDateTimeString))), 'xml');
561+
562+
$this->assertEquals($this->createXmlWithDateTimeField(), $actualXml);
563+
}
564+
565+
/**
566+
* @return XmlEncoder
567+
*/
568+
private function createXmlEncoderWithDateTimeNormalizer()
569+
{
570+
$encoder = new XmlEncoder();
571+
$serializer = new Serializer(array($this->createMockDateTimeNormalizer()), array('xml' => new XmlEncoder()));
572+
$encoder->setSerializer($serializer);
573+
574+
return $encoder;
575+
}
576+
577+
/**
578+
* @return \PHPUnit_Framework_MockObject_MockObject|NormalizerInterface
579+
*/
580+
private function createMockDateTimeNormalizer()
581+
{
582+
$mock = $this->getMockBuilder('\Symfony\Component\Serializer\Normalizer\CustomNormalizer')->getMock();
583+
584+
$mock
585+
->expects($this->once())
586+
->method('normalize')
587+
->with(new \DateTime($this->exampleDateTimeString), 'xml', array())
588+
->willReturn($this->exampleDateTimeString);
589+
590+
$mock
591+
->expects($this->once())
592+
->method('supportsNormalization')
593+
->with(new \DateTime($this->exampleDateTimeString), 'xml')
594+
->willReturn(true);
595+
596+
return $mock;
597+
}
598+
599+
/**
600+
* @return string
601+
*/
602+
private function createXmlWithDateTime()
603+
{
604+
return sprintf('<?xml version="1.0"?>
605+
<response><dateTime>%s</dateTime></response>
606+
', $this->exampleDateTimeString);
607+
}
608+
609+
/**
610+
* @return string
611+
*/
612+
private function createXmlWithDateTimeField()
613+
{
614+
return sprintf('<?xml version="1.0"?>
615+
<response><foo dateTime="%s"/></response>
616+
', $this->exampleDateTimeString);
617+
}
527618
}

0 commit comments

Comments
 (0)
0