From 0414c91dae51e3f50e60f09a6f1299b3fd30b581 Mon Sep 17 00:00:00 2001 From: Tom van Enckevort Date: Tue, 15 Apr 2025 09:48:44 +0100 Subject: [PATCH 1/2] Added custom RichTextRegexValidator to validate markup instead of JSON --- .../Validators/RegexValidator.cs | 4 +-- .../UmbracoBuilder.CoreServices.cs | 1 + .../PropertyEditors/RichTextPropertyEditor.cs | 10 ++++-- .../Validators/IRichTextRegexValidator.cs | 5 +++ .../Validators/RichTextRegexValidator.cs | 35 +++++++++++++++++++ 5 files changed, 51 insertions(+), 4 deletions(-) create mode 100644 src/Umbraco.Infrastructure/PropertyEditors/Validators/IRichTextRegexValidator.cs create mode 100644 src/Umbraco.Infrastructure/PropertyEditors/Validators/RichTextRegexValidator.cs diff --git a/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs index 5a9032303cf3..d6e65146bdcf 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs @@ -11,7 +11,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.Validators; /// /// A validator that validates that the value against a regular expression. /// -public sealed class RegexValidator : IValueFormatValidator, IManifestValueValidator +public class RegexValidator : IValueFormatValidator, IManifestValueValidator { private const string ValueIsInvalid = "Value is invalid, it does not match the correct pattern"; private readonly ILocalizedTextService _textService; @@ -83,7 +83,7 @@ public IEnumerable Validate(object? value, string? valueType, } /// - public IEnumerable ValidateFormat(object? value, string? valueType, string format) + public virtual IEnumerable ValidateFormat(object? value, string? valueType, string format) { if (format == null) { diff --git a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs index ef0e25204c60..83f43e099cd0 100644 --- a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs +++ b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs @@ -240,6 +240,7 @@ public static IUmbracoBuilder AddCoreInitialServices(this IUmbracoBuilder builde builder.Services.AddSingleton(); builder.Services.AddSingleton(); + builder.Services.AddSingleton(); return builder; } diff --git a/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs index 772e72283377..604a557261ea 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs @@ -176,6 +176,7 @@ internal class RichTextPropertyValueEditor : BlockValuePropertyValueEditorBase private readonly IJsonSerializer _jsonSerializer; private readonly IBlockEditorElementTypeCache _elementTypeCache; private readonly IRichTextRequiredValidator _richTextRequiredValidator; + private readonly IRichTextRegexValidator _richTextRegexValidator; private readonly ILogger _logger; [Obsolete("Use non-obsolete constructor. This is schedules for removal in v16.")] @@ -215,7 +216,8 @@ public RichTextPropertyValueEditor( elementTypeCache, propertyValidationService, dataValueReferenceFactoryCollection, - StaticServiceProvider.Instance.GetRequiredService()) + StaticServiceProvider.Instance.GetRequiredService(), + StaticServiceProvider.Instance.GetRequiredService()) { } @@ -237,7 +239,8 @@ public RichTextPropertyValueEditor( IBlockEditorElementTypeCache elementTypeCache, IPropertyValidationService propertyValidationService, DataValueReferenceFactoryCollection dataValueReferenceFactoryCollection, - IRichTextRequiredValidator richTextRequiredValidator) + IRichTextRequiredValidator richTextRequiredValidator, + IRichTextRegexValidator richTextRegexValidator) : base(attribute, propertyEditors, dataTypeReadCache, localizedTextService, logger, shortStringHelper, jsonSerializer, ioHelper, dataValueReferenceFactoryCollection) { _backOfficeSecurityAccessor = backOfficeSecurityAccessor; @@ -249,6 +252,7 @@ public RichTextPropertyValueEditor( _macroParameterParser = macroParameterParser; _elementTypeCache = elementTypeCache; _richTextRequiredValidator = richTextRequiredValidator; + _richTextRegexValidator = richTextRegexValidator; _jsonSerializer = jsonSerializer; _logger = logger; @@ -257,6 +261,8 @@ public RichTextPropertyValueEditor( public override IValueRequiredValidator RequiredValidator => _richTextRequiredValidator; + public override IValueFormatValidator FormatValidator => _richTextRegexValidator; + /// public override object? Configuration { diff --git a/src/Umbraco.Infrastructure/PropertyEditors/Validators/IRichTextRegexValidator.cs b/src/Umbraco.Infrastructure/PropertyEditors/Validators/IRichTextRegexValidator.cs new file mode 100644 index 000000000000..8b6955432215 --- /dev/null +++ b/src/Umbraco.Infrastructure/PropertyEditors/Validators/IRichTextRegexValidator.cs @@ -0,0 +1,5 @@ +namespace Umbraco.Cms.Core.PropertyEditors.Validators; + +internal interface IRichTextRegexValidator : IValueFormatValidator +{ +} diff --git a/src/Umbraco.Infrastructure/PropertyEditors/Validators/RichTextRegexValidator.cs b/src/Umbraco.Infrastructure/PropertyEditors/Validators/RichTextRegexValidator.cs new file mode 100644 index 000000000000..4c8684db2ca5 --- /dev/null +++ b/src/Umbraco.Infrastructure/PropertyEditors/Validators/RichTextRegexValidator.cs @@ -0,0 +1,35 @@ +using System.ComponentModel.DataAnnotations; +using Microsoft.Extensions.Logging; +using Umbraco.Cms.Core.Serialization; +using Umbraco.Cms.Core.Services; + +namespace Umbraco.Cms.Core.PropertyEditors.Validators; + +internal class RichTextRegexValidator : RegexValidator, IRichTextRegexValidator +{ + private readonly IJsonSerializer _jsonSerializer; + private readonly ILogger _logger; + + public RichTextRegexValidator(ILocalizedTextService textService, IJsonSerializer jsonSerializer, ILogger logger) + : this(textService, string.Empty, jsonSerializer, logger) + { + } + + public RichTextRegexValidator(ILocalizedTextService textService, string regex, IJsonSerializer jsonSerializer, ILogger logger) : base(textService, regex) + { + _jsonSerializer = jsonSerializer; + _logger = logger; + } + + public override IEnumerable ValidateFormat(object? value, string? valueType, string format) => base.ValidateFormat(GetValue(value), valueType, format); + + private object? GetValue(object? value) + { + if (RichTextPropertyEditorHelper.TryParseRichTextEditorValue(value, _jsonSerializer, _logger, out RichTextEditorValue? richTextEditorValue)) + { + return richTextEditorValue?.Markup; + } + + return value; + } +} From a77bea24d687267fafee92e93e4d0ef5df6681f5 Mon Sep 17 00:00:00 2001 From: Migaroez Date: Mon, 5 May 2025 19:41:30 +0200 Subject: [PATCH 2/2] Fix breaking changes --- .../Validators/RegexValidator.cs | 4 +- .../PropertyEditors/RichTextPropertyEditor.cs | 44 ++++++++++++++++++- .../Validators/RichTextRegexValidator.cs | 29 +++++------- 3 files changed, 57 insertions(+), 20 deletions(-) diff --git a/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs index d6e65146bdcf..5a9032303cf3 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/Validators/RegexValidator.cs @@ -11,7 +11,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.Validators; /// /// A validator that validates that the value against a regular expression. /// -public class RegexValidator : IValueFormatValidator, IManifestValueValidator +public sealed class RegexValidator : IValueFormatValidator, IManifestValueValidator { private const string ValueIsInvalid = "Value is invalid, it does not match the correct pattern"; private readonly ILocalizedTextService _textService; @@ -83,7 +83,7 @@ public IEnumerable Validate(object? value, string? valueType, } /// - public virtual IEnumerable ValidateFormat(object? value, string? valueType, string format) + public IEnumerable ValidateFormat(object? value, string? valueType, string format) { if (format == null) { diff --git a/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs index 604a557261ea..902f9da3c24f 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs @@ -219,8 +219,50 @@ public RichTextPropertyValueEditor( StaticServiceProvider.Instance.GetRequiredService(), StaticServiceProvider.Instance.GetRequiredService()) { - } + + public RichTextPropertyValueEditor( + DataEditorAttribute attribute, + PropertyEditorCollection propertyEditors, + IDataTypeConfigurationCache dataTypeReadCache, + ILogger logger, + IBackOfficeSecurityAccessor backOfficeSecurityAccessor, + ILocalizedTextService localizedTextService, + IShortStringHelper shortStringHelper, + HtmlImageSourceParser imageSourceParser, + HtmlLocalLinkParser localLinkParser, + RichTextEditorPastedImages pastedImages, + IJsonSerializer jsonSerializer, + IIOHelper ioHelper, + IHtmlSanitizer htmlSanitizer, + IHtmlMacroParameterParser macroParameterParser, + IBlockEditorElementTypeCache elementTypeCache, + IPropertyValidationService propertyValidationService, + DataValueReferenceFactoryCollection dataValueReferenceFactoryCollection, + IRichTextRequiredValidator richTextRequiredValidator) + : this( + attribute, + propertyEditors, + dataTypeReadCache, + logger, + backOfficeSecurityAccessor, + localizedTextService, + shortStringHelper, + imageSourceParser, + localLinkParser, + pastedImages, + jsonSerializer, + ioHelper, + htmlSanitizer, + macroParameterParser, + elementTypeCache, + propertyValidationService, + dataValueReferenceFactoryCollection, + richTextRequiredValidator, + StaticServiceProvider.Instance.GetRequiredService()) + { + } + public RichTextPropertyValueEditor( DataEditorAttribute attribute, PropertyEditorCollection propertyEditors, diff --git a/src/Umbraco.Infrastructure/PropertyEditors/Validators/RichTextRegexValidator.cs b/src/Umbraco.Infrastructure/PropertyEditors/Validators/RichTextRegexValidator.cs index 4c8684db2ca5..aefbe3a5deaa 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/Validators/RichTextRegexValidator.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/Validators/RichTextRegexValidator.cs @@ -5,31 +5,26 @@ namespace Umbraco.Cms.Core.PropertyEditors.Validators; -internal class RichTextRegexValidator : RegexValidator, IRichTextRegexValidator +internal class RichTextRegexValidator : IRichTextRegexValidator { + private readonly RegexValidator _regexValidator; private readonly IJsonSerializer _jsonSerializer; private readonly ILogger _logger; - public RichTextRegexValidator(ILocalizedTextService textService, IJsonSerializer jsonSerializer, ILogger logger) - : this(textService, string.Empty, jsonSerializer, logger) - { - } - - public RichTextRegexValidator(ILocalizedTextService textService, string regex, IJsonSerializer jsonSerializer, ILogger logger) : base(textService, regex) + public RichTextRegexValidator( + IJsonSerializer jsonSerializer, + ILogger logger, + RegexValidator regexValidator) { _jsonSerializer = jsonSerializer; _logger = logger; + _regexValidator = regexValidator; } - public override IEnumerable ValidateFormat(object? value, string? valueType, string format) => base.ValidateFormat(GetValue(value), valueType, format); + public IEnumerable ValidateFormat(object? value, string? valueType, string format) => _regexValidator.ValidateFormat(GetValue(value), valueType, format); - private object? GetValue(object? value) - { - if (RichTextPropertyEditorHelper.TryParseRichTextEditorValue(value, _jsonSerializer, _logger, out RichTextEditorValue? richTextEditorValue)) - { - return richTextEditorValue?.Markup; - } - - return value; - } + private object? GetValue(object? value) => + RichTextPropertyEditorHelper.TryParseRichTextEditorValue(value, _jsonSerializer, _logger, out RichTextEditorValue? richTextEditorValue) + ? richTextEditorValue?.Markup + : value; }