diff --git a/bundles/CoreBundle/config/pimcore/default.yaml b/bundles/CoreBundle/config/pimcore/default.yaml index 7225fa5501e..34cca646e7e 100644 --- a/bundles/CoreBundle/config/pimcore/default.yaml +++ b/bundles/CoreBundle/config/pimcore/default.yaml @@ -74,6 +74,19 @@ framework: ul: ['class', 'style', 'id'] li: ['class', 'style', 'id'] ol: ['class', 'style', 'id'] + pimcore.translation_sanitizer: + allow_elements: + span: [ 'class', 'style', 'id' ] + p: [ 'class', 'style', 'id' ] + strong: 'class' + em: 'class' + h1: [ 'class', 'id' ] + h2: [ 'class', 'id' ] + h3: [ 'class', 'id' ] + h4: [ 'class', 'id' ] + h5: [ 'class', 'id' ] + h6: [ 'class', 'id' ] + a: [ 'class', 'id', 'href', 'target', 'title', 'rel' ] # Twig Configuration twig: diff --git a/bundles/CoreBundle/src/DependencyInjection/Compiler/TranslationSanitizerPass.php b/bundles/CoreBundle/src/DependencyInjection/Compiler/TranslationSanitizerPass.php new file mode 100644 index 00000000000..4133b8b3535 --- /dev/null +++ b/bundles/CoreBundle/src/DependencyInjection/Compiler/TranslationSanitizerPass.php @@ -0,0 +1,32 @@ +getDefinition('html_sanitizer.sanitizer.pimcore.translation_sanitizer')->setPublic(true); + } +} diff --git a/bundles/CoreBundle/src/PimcoreCoreBundle.php b/bundles/CoreBundle/src/PimcoreCoreBundle.php index 00cc2a5f32c..1ae14111bea 100644 --- a/bundles/CoreBundle/src/PimcoreCoreBundle.php +++ b/bundles/CoreBundle/src/PimcoreCoreBundle.php @@ -30,6 +30,7 @@ use Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler\RoutingLoaderPass; use Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler\SerializerPass; use Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler\ServiceControllersPass; +use Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler\TranslationSanitizerPass; use Pimcore\Bundle\CoreBundle\DependencyInjection\Compiler\WorkflowPass; use Symfony\Component\DependencyInjection\ContainerBuilder; use Symfony\Component\DependencyInjection\Extension\ExtensionInterface; @@ -82,6 +83,7 @@ public function build(ContainerBuilder $container): void $container->addCompilerPass(new CacheFallbackPass()); $container->addCompilerPass(new MessageBusPublicPass()); $container->addCompilerPass(new HtmlSanitizerPass()); + $container->addCompilerPass(new TranslationSanitizerPass()); $container->addCompilerPass(new SerializerPass()); } diff --git a/doc/23_Installation_and_Upgrade/09_Upgrade_Notes/README.md b/doc/23_Installation_and_Upgrade/09_Upgrade_Notes/README.md index 0bce9fbc482..2796c1f3431 100644 --- a/doc/23_Installation_and_Upgrade/09_Upgrade_Notes/README.md +++ b/doc/23_Installation_and_Upgrade/09_Upgrade_Notes/README.md @@ -334,6 +334,7 @@ pimcore: - [WebDAV] WebDAV url has been changed from `https://YOUR-DOMAIN/admin/asset/webdav` to `https://YOUR-DOMAIN/asset/webdav` - [Events] `AdminEvents::ELEMENT_PERMISSION_IS_ALLOWED` has been renamed to `Pimcore\Event\ElementEvents::ELEMENT_PERMISSION_IS_ALLOWED`. - [Wysiwyg] Implemented Symfony HTML sanitizer for WYSIWYG editor. +- [Translations] Added Symfony's html sanitizer to `\Pimcore\Model\Translation\Dao::save` method. - [Editable] Removed the `attributes` field from the link editable. ## 10.6.0 diff --git a/lib/Tool/Text.php b/lib/Tool/Text.php index 44cdbda6964..e2c145b67c3 100644 --- a/lib/Tool/Text.php +++ b/lib/Tool/Text.php @@ -27,6 +27,8 @@ class Text { public const PIMCORE_WYSIWYG_SANITIZER_ID = 'html_sanitizer.sanitizer.pimcore.wysiwyg_sanitizer'; + public const PIMCORE_TRANSLATION_SANITIZER_ID = 'html_sanitizer.sanitizer.pimcore.translation_sanitizer'; + public static function removeLineBreaks(string $text = ''): string { $text = str_replace(["\r\n", "\n", "\r", "\t"], ' ', $text); diff --git a/models/Translation.php b/models/Translation.php index 1ce693438c8..0745256aba4 100644 --- a/models/Translation.php +++ b/models/Translation.php @@ -27,6 +27,7 @@ use Pimcore\Tool; use Pimcore\Translation\TranslationEntriesDumper; use Symfony\Component\Filesystem\Filesystem; +use Symfony\Component\HtmlSanitizer\HtmlSanitizerInterface; use Symfony\Component\Translation\Exception\NotFoundResourceException; /** @@ -65,6 +66,13 @@ final class Translation extends AbstractModel */ protected ?int $userModification = null; + protected ?HtmlSanitizerInterface $pimcoreTranslationSanitizer = null; + + public function getTranslationSanitizer(): HtmlSanitizerInterface + { + return $this->pimcoreTranslationSanitizer ??= \Pimcore::getContainer()->get(Tool\Text::PIMCORE_TRANSLATION_SANITIZER_ID); + } + public function getType(): string { return $this->type ?: 'simple'; diff --git a/models/Translation/Dao.php b/models/Translation/Dao.php index b01e39c11d9..93a73934af0 100644 --- a/models/Translation/Dao.php +++ b/models/Translation/Dao.php @@ -83,6 +83,7 @@ public function save(): void $this->createOrUpdateTable(); $this->updateModificationInfos(); + $sanitizer = $this->model->getTranslationSanitizer(); $editableLanguages = []; if ($this->model->getDomain() != Model\Translation::DOMAIN_ADMIN) { @@ -104,7 +105,7 @@ public function save(): void 'key' => $this->model->getKey(), 'type' => $this->model->getType(), 'language' => $language, - 'text' => $text, + 'text' => $sanitizer->sanitize($text), 'modificationDate' => $this->model->getModificationDate(), 'creationDate' => $this->model->getCreationDate(), 'userOwner' => $this->model->getUserOwner(),