Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 65280e9

Browse files
committed
Issue-21617 Xml encoder throws exception for valid data
* add tests for bool and object encoding * fix encoding for object in array and field
1 parent 00c61da commit 65280e9

File tree

2 files changed

+111
-6
lines changed

2 files changed

+111
-6
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: 106 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,19 +11,29 @@
1111

1212
namespace Symfony\Component\Serializer\Tests\Encoder;
1313

14+
use DateTime;
1415
use PHPUnit\Framework\TestCase;
15-
use Symfony\Component\Serializer\Tests\Fixtures\Dummy;
16-
use Symfony\Component\Serializer\Tests\Fixtures\NormalizableTraversableDummy;
17-
use Symfony\Component\Serializer\Tests\Fixtures\ScalarDummy;
1816
use Symfony\Component\Serializer\Encoder\XmlEncoder;
19-
use Symfony\Component\Serializer\Serializer;
2017
use Symfony\Component\Serializer\Exception\UnexpectedValueException;
2118
use Symfony\Component\Serializer\Normalizer\CustomNormalizer;
19+
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
20+
use Symfony\Component\Serializer\Serializer;
21+
use Symfony\Component\Serializer\Tests\Fixtures\Dummy;
22+
use Symfony\Component\Serializer\Tests\Fixtures\NormalizableTraversableDummy;
23+
use Symfony\Component\Serializer\Tests\Fixtures\ScalarDummy;
2224

2325
class XmlEncoderTest extends TestCase
2426
{
27+
/**
28+
* @var XmlEncoder
29+
*/
2530
private $encoder;
2631

32+
/**
33+
* @var string
34+
*/
35+
private $exampleDateTimeString = '2017-02-19T15:16:08+0300';
36+
2737
protected function setUp()
2838
{
2939
$this->encoder = new XmlEncoder();
@@ -524,4 +534,96 @@ protected function getObject()
524534

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

0 commit comments

Comments
 (0)