diff --git a/src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs b/src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs index e3abf0035f17..d0cf1b1606b9 100644 --- a/src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs +++ b/src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs @@ -1,4 +1,7 @@ +using System.ComponentModel.DataAnnotations; +using Microsoft.Extensions.DependencyInjection; using Umbraco.Cms.Core.Cache; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.IO; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Editors; @@ -66,7 +69,8 @@ public MediaPicker3PropertyValueEditor( ITemporaryFileService temporaryFileService, IScopeProvider scopeProvider, IBackOfficeSecurityAccessor backOfficeSecurityAccessor, - IDataTypeConfigurationCache dataTypeReadCache) + IDataTypeConfigurationCache dataTypeReadCache, + ILocalizedTextService localizedTextService) : base(shortStringHelper, jsonSerializer, ioHelper, attribute) { _jsonSerializer = jsonSerializer; @@ -76,6 +80,34 @@ public MediaPicker3PropertyValueEditor( _scopeProvider = scopeProvider; _backOfficeSecurityAccessor = backOfficeSecurityAccessor; _dataTypeReadCache = dataTypeReadCache; + Validators.Add(new MinMaxValidator(jsonSerializer, localizedTextService)); + } + + [Obsolete("Use non obsoleted constructor instead. Scheduled for removal in v17")] + public MediaPicker3PropertyValueEditor( + IShortStringHelper shortStringHelper, + IJsonSerializer jsonSerializer, + IIOHelper ioHelper, + DataEditorAttribute attribute, + IMediaImportService mediaImportService, + IMediaService mediaService, + ITemporaryFileService temporaryFileService, + IScopeProvider scopeProvider, + IBackOfficeSecurityAccessor backOfficeSecurityAccessor, + IDataTypeConfigurationCache dataTypeReadCache) + : this( + shortStringHelper, + jsonSerializer, + ioHelper, + attribute, + mediaImportService, + mediaService, + temporaryFileService, + scopeProvider, + backOfficeSecurityAccessor, + dataTypeReadCache, + StaticServiceProvider.Instance.GetRequiredService()) + { } /// @@ -294,5 +326,58 @@ public void ApplyConfiguration(MediaPicker3Configuration? configuration) } } } + + private class MinMaxValidator : IValueValidator + { + private readonly IJsonSerializer _jsonSerializer; + private readonly ILocalizedTextService _localizedTextService; + + public MinMaxValidator(IJsonSerializer jsonSerializer, ILocalizedTextService localizedTextService) + { + _jsonSerializer = jsonSerializer; + _localizedTextService = localizedTextService; + } + + public IEnumerable Validate(object? value, string? valueType, + object? dataTypeConfiguration) + { + var validationResults = new List(); + + if (dataTypeConfiguration is not MediaPicker3Configuration mediaPickerConfiguration) + { + return validationResults; + } + + if (value is null || + _jsonSerializer.TryDeserialize(value, out List? mediaWithCropsDtos) is false) + { + return validationResults; + } + + if (mediaPickerConfiguration.ValidationLimit.Min is not null + && mediaWithCropsDtos.Count < mediaPickerConfiguration.ValidationLimit.Min) + { + validationResults.Add(new ValidationResult( + _localizedTextService.Localize( + "validation", + "entriesShort", + new[] { mediaPickerConfiguration.ValidationLimit.Min.ToString(), (mediaPickerConfiguration.ValidationLimit.Min - mediaWithCropsDtos.Count).ToString(), }), + new[] { "validationLimit" })); + } + + if (mediaPickerConfiguration.ValidationLimit.Max is not null + && mediaWithCropsDtos.Count > mediaPickerConfiguration.ValidationLimit.Max) + { + validationResults.Add(new ValidationResult( + _localizedTextService.Localize( + "validation", + "entriesExceed", + new[] { mediaPickerConfiguration.ValidationLimit.Max.ToString(), (mediaWithCropsDtos.Count - mediaPickerConfiguration.ValidationLimit.Max).ToString(), }), + new[] { "validationLimit" })); + } + + return validationResults; + } + } } } diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollectionTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollectionTests.cs index cfaefed8b12f..931f39d8feba 100644 --- a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollectionTests.cs +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollectionTests.cs @@ -36,7 +36,8 @@ public class DataValueReferenceFactoryCollectionTests Mock.Of(), Mock.Of(), Mock.Of(), - Mock.Of())); + Mock.Of(), + Mock.Of())); private IIOHelper IOHelper { get; } = Mock.Of();