Skip to content

Commit d3ec14a

Browse files
author
Mateusz Dębiński
committed
IBX-10425: Translated string is returned as XML
1 parent bc9a25a commit d3ec14a

File tree

4 files changed

+82
-0
lines changed

4 files changed

+82
-0
lines changed

composer.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@
3232
"require": {
3333
"php": "^7.4 || ^8.0",
3434
"ext-libxml": "*",
35+
"ext-dom": "*",
3536
"symfony/yaml": "^5.0",
3637
"symfony/routing": "^5.0",
3738
"symfony/console": "^5.0",

phpstan-baseline.neon

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,18 @@ parameters:
3030
count: 1
3131
path: src/bundle/Form/TranslationAddDataTransformer.php
3232

33+
-
34+
message: '#^Call to an undefined method DOMNode\:\:getAttribute\(\)\.$#'
35+
identifier: method.notFound
36+
count: 1
37+
path: src/lib/Encoder.php
38+
39+
-
40+
message: '#^Call to an undefined method DOMNode\:\:getAttribute\(\)\.$#'
41+
identifier: method.notFound
42+
count: 1
43+
path: src/lib/Encoder/Field/PageBuilderFieldEncoder.php
44+
3345
-
3446
message: '#^Cannot call method setValue\(\) on Ibexa\\Contracts\\FieldTypePage\\FieldType\\LandingPage\\Model\\Attribute\|null\.$#'
3547
identifier: method.nonObject

src/lib/Encoder.php

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
namespace Ibexa\AutomatedTranslation;
1010

11+
use DOMCdataSection;
12+
use DOMDocument;
13+
use DOMXPath;
1114
use Ibexa\AutomatedTranslation\Encoder\Field\FieldEncoderManager;
1215
use Ibexa\AutomatedTranslation\Exception\EmptyTranslatedFieldException;
1316
use Ibexa\Bundle\AutomatedTranslation\Event\FieldDecodeEvent;
@@ -18,7 +21,9 @@
1821
use Ibexa\Contracts\Core\Repository\Values\Content\Content;
1922
use Ibexa\Contracts\Core\Repository\Values\Content\Field;
2023
use Ibexa\Core\FieldType\Value;
24+
use Ibexa\FieldTypeRichText\FieldType\RichText\Value as RichTextValue;
2125
use InvalidArgumentException;
26+
use RuntimeException;
2227
use Symfony\Component\Serializer\Encoder\XmlEncoder;
2328
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface;
2429

@@ -118,6 +123,36 @@ public function encode(Content $content): string
118123

119124
$encoder = new XmlEncoder();
120125
$payload = $encoder->encode($results, XmlEncoder::FORMAT);
126+
127+
$dom = new DOMDocument();
128+
$dom->loadXML($payload);
129+
$xpath = new DOMXPath($dom);
130+
$textNodes = $xpath->query('//text()');
131+
if ($textNodes !== false) {
132+
foreach ($textNodes as $textNode) {
133+
if ($textNode instanceof DOMCdataSection) {
134+
$parent = $textNode->parentNode;
135+
if ($parent === null) {
136+
continue;
137+
}
138+
139+
$type = $parent->getAttribute('type');
140+
141+
if ($type !== RichTextValue::class) {
142+
$newText = $dom->createTextNode($textNode->data);
143+
$parent->replaceChild($newText, $textNode);
144+
}
145+
}
146+
}
147+
$payload = $dom->saveXML();
148+
149+
if (!$payload) {
150+
throw new RuntimeException(
151+
sprintf('Saving XML failed after removing CDATA, error: %s', preg_last_error_msg())
152+
);
153+
}
154+
}
155+
121156
// here Encoder has decorated with CDATA, we don't want the CDATA
122157
return str_replace(
123158
['<![CDATA[', ']]>'],

src/lib/Encoder/Field/PageBuilderFieldEncoder.php

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,19 @@
88

99
namespace Ibexa\AutomatedTranslation\Encoder\Field;
1010

11+
use DOMCdataSection;
12+
use DOMDocument;
13+
use DOMXPath;
1114
use Ibexa\AutomatedTranslation\Encoder\BlockAttribute\BlockAttributeEncoderManager;
1215
use Ibexa\AutomatedTranslation\Exception\EmptyTranslatedAttributeException;
1316
use Ibexa\Contracts\AutomatedTranslation\Encoder\Field\FieldEncoderInterface;
1417
use Ibexa\Contracts\Core\Repository\Values\Content\Field;
1518
use Ibexa\Core\FieldType\Value as APIValue;
1619
use Ibexa\FieldTypePage\FieldType\LandingPage\Value;
1720
use Ibexa\FieldTypePage\FieldType\Page\Block\Definition\BlockDefinitionFactoryInterface;
21+
use Ibexa\FieldTypeRichText\FieldType\RichText\Value as RichTextValue;
1822
use InvalidArgumentException;
23+
use RuntimeException;
1924
use Symfony\Component\Serializer\Encoder\XmlEncoder;
2025

2126
final class PageBuilderFieldEncoder implements FieldEncoderInterface
@@ -84,6 +89,35 @@ public function encode(Field $field): string
8489
XmlEncoder::ROOT_NODE_NAME => 'blocks',
8590
]);
8691

92+
$dom = new DOMDocument();
93+
$dom->loadXML($payload);
94+
$xpath = new DOMXPath($dom);
95+
$textNodes = $xpath->query('//text()');
96+
if ($textNodes !== false) {
97+
foreach ($textNodes as $textNode) {
98+
if ($textNode instanceof DOMCdataSection) {
99+
$parent = $textNode->parentNode;
100+
if ($parent === null) {
101+
continue;
102+
}
103+
104+
$type = $parent->getAttribute('type');
105+
106+
if ($type !== RichTextValue::class) {
107+
$newText = $dom->createTextNode($textNode->data);
108+
$parent->replaceChild($newText, $textNode);
109+
}
110+
}
111+
}
112+
$payload = $dom->saveXML();
113+
114+
if (!$payload) {
115+
throw new RuntimeException(
116+
sprintf('Saving XML failed after removing CDATA, error: %s', preg_last_error_msg())
117+
);
118+
}
119+
}
120+
87121
$payload = str_replace('<?xml version="1.0"?>' . "\n", '', $payload);
88122

89123
$payload = str_replace(

0 commit comments

Comments
 (0)