diff --git a/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs b/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs index 296e8eed36..1bf19b361b 100644 --- a/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs +++ b/src/Umbraco.Core/PropertyEditors/Validators/RequiredValidator.cs @@ -7,7 +7,7 @@ namespace Umbraco.Cms.Core.PropertyEditors.Validators; /// /// A validator that validates that the value is not null or empty (if it is a string) /// -public sealed class RequiredValidator : IValueRequiredValidator, IManifestValueValidator +public class RequiredValidator : IValueRequiredValidator, IManifestValueValidator { private const string ValueCannotBeNull = "Value cannot be null"; private const string ValueCannotBeEmpty = "Value cannot be empty"; @@ -23,7 +23,7 @@ public sealed class RequiredValidator : IValueRequiredValidator, IManifestValueV ValidateRequired(value, valueType); /// - public IEnumerable ValidateRequired(object? value, string? valueType) + public virtual IEnumerable ValidateRequired(object? value, string? valueType) { if (value == null) { diff --git a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs index 77194cef2e..a9ffc67f64 100644 --- a/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs +++ b/src/Umbraco.Infrastructure/DependencyInjection/UmbracoBuilder.CoreServices.cs @@ -28,6 +28,7 @@ using Umbraco.Cms.Core.Models.PublishedContent; using Umbraco.Cms.Core.Notifications; using Umbraco.Cms.Core.Packaging; using Umbraco.Cms.Core.PropertyEditors; +using Umbraco.Cms.Core.PropertyEditors.Validators; using Umbraco.Cms.Core.PropertyEditors.ValueConverters; using Umbraco.Cms.Core.PublishedCache; using Umbraco.Cms.Core.Routing; @@ -238,6 +239,8 @@ public static partial class UmbracoBuilderExtensions 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 ee37d8c63b..772e722833 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/RichTextPropertyEditor.cs @@ -12,6 +12,7 @@ using Umbraco.Cms.Core.Media; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Blocks; using Umbraco.Cms.Core.Models.Editors; +using Umbraco.Cms.Core.PropertyEditors.Validators; using Umbraco.Cms.Core.Security; using Umbraco.Cms.Core.Serialization; using Umbraco.Cms.Core.Services; @@ -166,6 +167,7 @@ public class RichTextPropertyEditor : DataEditor internal class RichTextPropertyValueEditor : BlockValuePropertyValueEditorBase { private readonly IBackOfficeSecurityAccessor _backOfficeSecurityAccessor; + private readonly ILocalizedTextService _localizedTextService; private readonly IHtmlSanitizer _htmlSanitizer; private readonly HtmlImageSourceParser _imageSourceParser; private readonly HtmlLocalLinkParser _localLinkParser; @@ -173,8 +175,10 @@ public class RichTextPropertyEditor : DataEditor private readonly RichTextEditorPastedImages _pastedImages; private readonly IJsonSerializer _jsonSerializer; private readonly IBlockEditorElementTypeCache _elementTypeCache; + private readonly IRichTextRequiredValidator _richTextRequiredValidator; private readonly ILogger _logger; + [Obsolete("Use non-obsolete constructor. This is schedules for removal in v16.")] public RichTextPropertyValueEditor( DataEditorAttribute attribute, PropertyEditorCollection propertyEditors, @@ -193,21 +197,66 @@ public class RichTextPropertyEditor : DataEditor IBlockEditorElementTypeCache elementTypeCache, IPropertyValidationService propertyValidationService, DataValueReferenceFactoryCollection dataValueReferenceFactoryCollection) + : this( + attribute, + propertyEditors, + dataTypeReadCache, + logger, + backOfficeSecurityAccessor, + localizedTextService, + shortStringHelper, + imageSourceParser, + localLinkParser, + pastedImages, + jsonSerializer, + ioHelper, + htmlSanitizer, + macroParameterParser, + elementTypeCache, + propertyValidationService, + dataValueReferenceFactoryCollection, + 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) : base(attribute, propertyEditors, dataTypeReadCache, localizedTextService, logger, shortStringHelper, jsonSerializer, ioHelper, dataValueReferenceFactoryCollection) { _backOfficeSecurityAccessor = backOfficeSecurityAccessor; + _localizedTextService = localizedTextService; _imageSourceParser = imageSourceParser; _localLinkParser = localLinkParser; _pastedImages = pastedImages; _htmlSanitizer = htmlSanitizer; _macroParameterParser = macroParameterParser; _elementTypeCache = elementTypeCache; + _richTextRequiredValidator = richTextRequiredValidator; _jsonSerializer = jsonSerializer; _logger = logger; Validators.Add(new RichTextEditorBlockValidator(propertyValidationService, CreateBlockEditorValues(), elementTypeCache, jsonSerializer, logger)); } + public override IValueRequiredValidator RequiredValidator => _richTextRequiredValidator; + /// public override object? Configuration { diff --git a/src/Umbraco.Infrastructure/PropertyEditors/Validators/IRichTextRequiredValidator.cs b/src/Umbraco.Infrastructure/PropertyEditors/Validators/IRichTextRequiredValidator.cs new file mode 100644 index 0000000000..7358e92f38 --- /dev/null +++ b/src/Umbraco.Infrastructure/PropertyEditors/Validators/IRichTextRequiredValidator.cs @@ -0,0 +1,7 @@ +using Umbraco.Cms.Core.PropertyEditors; + +namespace Umbraco.Cms.Core.PropertyEditors.Validators; + +internal interface IRichTextRequiredValidator : IValueRequiredValidator +{ +} diff --git a/src/Umbraco.Infrastructure/PropertyEditors/Validators/RichTextRequiredValidator.cs b/src/Umbraco.Infrastructure/PropertyEditors/Validators/RichTextRequiredValidator.cs new file mode 100644 index 0000000000..b239f0bda5 --- /dev/null +++ b/src/Umbraco.Infrastructure/PropertyEditors/Validators/RichTextRequiredValidator.cs @@ -0,0 +1,30 @@ +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 RichTextRequiredValidator : RequiredValidator, IRichTextRequiredValidator +{ + private readonly IJsonSerializer _jsonSerializer; + private readonly ILogger _logger; + + public RichTextRequiredValidator(ILocalizedTextService textService, IJsonSerializer jsonSerializer, ILogger logger) : base(textService) + { + _jsonSerializer = jsonSerializer; + _logger = logger; + } + + public override IEnumerable ValidateRequired(object? value, string? valueType) => base.ValidateRequired(GetValue(value), valueType); + + private object? GetValue(object? value) + { + if(RichTextPropertyEditorHelper.TryParseRichTextEditorValue(value, _jsonSerializer, _logger, out RichTextEditorValue? richTextEditorValue)) + { + return richTextEditorValue?.Markup; + } + + return value; + } +}