Skip to content

Commit 129bb3f

Browse files
committed
[Serializer] Add XmlEncoder::CDATA_WRAPPING_PATTERN context option
1 parent f738888 commit 129bb3f

File tree

5 files changed

+33
-2
lines changed

5 files changed

+33
-2
lines changed

src/Symfony/Component/Serializer/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ CHANGELOG
1010
* Add `AbstractNormalizer::FILTER_BOOL` context option
1111
* Add `CamelCaseToSnakeCaseNameConverter::REQUIRE_SNAKE_CASE_PROPERTIES` context option
1212
* Deprecate `AbstractNormalizerContextBuilder::withDefaultContructorArguments(?array $defaultContructorArguments)`, use `withDefaultConstructorArguments(?array $defaultConstructorArguments)` instead (note the missing `s` character in Contructor word in deprecated method)
13+
* Add `XmlEncoder::CDATA_WRAPPING_PATTERN` context option
1314

1415
7.0
1516
---

src/Symfony/Component/Serializer/Context/Encoder/XmlEncoderContextBuilder.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,4 +152,12 @@ public function withCdataWrapping(?bool $cdataWrapping): static
152152
{
153153
return $this->with(XmlEncoder::CDATA_WRAPPING, $cdataWrapping);
154154
}
155+
156+
/**
157+
* Configures the pattern used to evaluate if a CDATA section should be added.
158+
*/
159+
public function withCdataWrappingPattern(?string $cdataWrappingPattern): static
160+
{
161+
return $this->with(XmlEncoder::CDATA_WRAPPING_PATTERN, $cdataWrappingPattern);
162+
}
155163
}

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa
5959
public const TYPE_CAST_ATTRIBUTES = 'xml_type_cast_attributes';
6060
public const VERSION = 'xml_version';
6161
public const CDATA_WRAPPING = 'cdata_wrapping';
62+
public const CDATA_WRAPPING_PATTERN = 'cdata_wrapping_pattern';
6263

6364
private array $defaultContext = [
6465
self::AS_COLLECTION => false,
@@ -70,6 +71,7 @@ class XmlEncoder implements EncoderInterface, DecoderInterface, NormalizationAwa
7071
self::ROOT_NODE_NAME => 'response',
7172
self::TYPE_CAST_ATTRIBUTES => true,
7273
self::CDATA_WRAPPING => true,
74+
self::CDATA_WRAPPING_PATTERN => '/[<>&]/',
7375
];
7476

7577
public function __construct(array $defaultContext = [])
@@ -433,7 +435,7 @@ private function appendNode(\DOMNode $parentNode, mixed $data, string $format, a
433435
*/
434436
private function needsCdataWrapping(string $val, array $context): bool
435437
{
436-
return ($context[self::CDATA_WRAPPING] ?? $this->defaultContext[self::CDATA_WRAPPING]) && preg_match('/[<>&]/', $val);
438+
return ($context[self::CDATA_WRAPPING] ?? $this->defaultContext[self::CDATA_WRAPPING]) && preg_match($context[self::CDATA_WRAPPING_PATTERN] ?? $this->defaultContext[self::CDATA_WRAPPING_PATTERN], $val);
437439
}
438440

439441
/**

src/Symfony/Component/Serializer/Tests/Context/Encoder/XmlEncoderContextBuilderTest.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@ public function testWithers(array $values)
4646
->withTypeCastAttributes($values[XmlEncoder::TYPE_CAST_ATTRIBUTES])
4747
->withVersion($values[XmlEncoder::VERSION])
4848
->withCdataWrapping($values[XmlEncoder::CDATA_WRAPPING])
49+
->withCdataWrappingPattern($values[XmlEncoder::CDATA_WRAPPING_PATTERN])
4950
->toArray();
5051

5152
$this->assertSame($values, $context);
@@ -67,6 +68,7 @@ public static function withersDataProvider(): iterable
6768
XmlEncoder::TYPE_CAST_ATTRIBUTES => true,
6869
XmlEncoder::VERSION => '1.0',
6970
XmlEncoder::CDATA_WRAPPING => false,
71+
XmlEncoder::CDATA_WRAPPING_PATTERN => '/[<>&"\']/',
7072
]];
7173

7274
yield 'With null values' => [[
@@ -83,6 +85,7 @@ public static function withersDataProvider(): iterable
8385
XmlEncoder::TYPE_CAST_ATTRIBUTES => null,
8486
XmlEncoder::VERSION => null,
8587
XmlEncoder::CDATA_WRAPPING => null,
88+
XmlEncoder::CDATA_WRAPPING_PATTERN => null,
8689
]];
8790
}
8891
}

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

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -231,7 +231,7 @@ public function testEncodeRootAttributes()
231231
$this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
232232
}
233233

234-
public function testEncodeCdataWrapping()
234+
public function testEncodeCdataWrappingWithDefaultPattern()
235235
{
236236
$array = [
237237
'firstname' => 'Paul & Martha <or Me>',
@@ -243,6 +243,23 @@ public function testEncodeCdataWrapping()
243243
$this->assertEquals($expected, $this->encoder->encode($array, 'xml'));
244244
}
245245

246+
public function testEncodeCdataWrappingWithCustomPattern()
247+
{
248+
$array = [
249+
'lastname' => 'O\'Donnel',
250+
];
251+
252+
$expectedUnwrapped = '<?xml version="1.0"?>'."\n".
253+
'<response><lastname>O\'Donnel</lastname></response>'."\n";
254+
255+
$this->assertSame($expectedUnwrapped, $this->encoder->encode($array, 'xml'));
256+
257+
$expectedWrapped = '<?xml version="1.0"?>'."\n".
258+
'<response><lastname><![CDATA[O\'Donnel]]></lastname></response>'."\n";
259+
260+
$this->assertSame($expectedWrapped, $this->encoder->encode($array, 'xml', ['cdata_wrapping_pattern' => '/[<>&"\']/']));
261+
}
262+
246263
public function testEnableCdataWrapping()
247264
{
248265
$array = [

0 commit comments

Comments
 (0)