IBX-12106: Fixed handling of invalid xml:id values in RichText - #343
Conversation
b4e6e8b to
f3ee157
Compare
| */ | ||
| declare(strict_types=1); | ||
|
|
||
| namespace Ibexa\Contracts\FieldTypeRichText\RichText; |
There was a problem hiding this comment.
It's not a Contract - external packages should not be able to use it. Afaik you only add this interface because you need it for tests. It can live alongside the implementation.
There was a problem hiding this comment.
It’s not only for tests. The deprecation points developers to this service, so I thought it belongs in Contracts.
a8d95a7 to
1ee97f7
Compare
3bf2e45 to
60810e7
Compare
60810e7 to
f393e87
Compare
alongosz
left a comment
There was a problem hiding this comment.
+1, given my last remark is about the pre-existing code in a different form, that just would be nice to have fixed here.
71faf1f to
7189cdb
Compare
|
KamilSznajdrowicz
left a comment
There was a problem hiding this comment.
QA Approved
PR tested on 4.6.x-dev, patch applied and successfully tested on v4.6.32



Description:
Pasting external HTML into a RichText field can bring ids which are not valid XML
xml:idvalues (e.g.id="227",id="foo bar"). Since EZP-31574 draft saves skip validation, so such ids get stored in DocBook. Every laterloadXML()of that content emits a libxml warning, which Symfony's error handler turns into an exception — the content can no longer be rendered or deleted.Two fixes:
XmlIdinput converter (priority 60, right after the XSLT) fixes invalidxml:idvalues on save: invalid characters become_, ids starting with a digit get a_prefix, collisions get a_1suffix. Internal anchor links (xlink:href="#...") are updated to match, so they keep working.DOMDocumentLoaderInterfaceservice (DOMDocumentLoader) loads already stored XML without emitting libxml warnings — errors are logged instead (Monolog channelibexa.richtext), with content/version/field ID where available. It is injected intoType::fromPersistenceValue(),RichTextStorage,SearchFieldand RESTRichTextProcessor, so content broken before this fix renders again and can be edited or deleted. Re-saving it fixes the stored ids.Passing a string to
Value::__construct()is now deprecated (since 4.6.33, only\DOMDocumentin 6.0) — load the document with the new service instead.For QA:
<p id="227">text</p>and<a href="#227">link</a>, save/publish — no error, and the stored DocBook containsxml:id="_227"andxlink:href="#_227".xml:id="227") — its page, draft edit page, restore from trash and send to trash all work without a 500._227.RichText XML document loaded with libxml errorswithcontentId/versionNo/fieldIdin the context, on theibexa.richtextchannel (ibexa.richtext.WARNINGinvar/log/dev.log).Documentation:
Ibexa\Contracts\FieldTypeRichText\RichText\DOMDocumentLoaderInterfaceservice for loading stored RichText XML.ibexa.richtextused byDOMDocumentLoaderandRichTextStorage.new Value(string $xml)— pass\DOMDocumentinstead; the string argument will be removed in 6.0.