Skip to content

Commit 0b9855c

Browse files
authored
Merge pull request #17762 from umbraco/v15/task/media-picker-min-max-validation
V15 min/max validator for mediapicker
2 parents cd25c9a + ddeb253 commit 0b9855c

File tree

2 files changed

+92
-2
lines changed

2 files changed

+92
-2
lines changed

src/Umbraco.Infrastructure/PropertyEditors/MediaPicker3PropertyEditor.cs

Lines changed: 90 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,12 @@
1+
using System.ComponentModel.DataAnnotations;
2+
using Microsoft.Extensions.DependencyInjection;
13
using Umbraco.Cms.Core.Cache;
4+
using Umbraco.Cms.Core.DependencyInjection;
25
using Umbraco.Cms.Core.IO;
36
using Umbraco.Cms.Core.Models;
47
using Umbraco.Cms.Core.Models.Editors;
58
using Umbraco.Cms.Core.Models.TemporaryFile;
9+
using Umbraco.Cms.Core.Models.Validation;
610
using Umbraco.Cms.Core.PropertyEditors.ValueConverters;
711
using Umbraco.Cms.Core.Security;
812
using Umbraco.Cms.Core.Serialization;
@@ -66,7 +70,8 @@ public MediaPicker3PropertyValueEditor(
6670
ITemporaryFileService temporaryFileService,
6771
IScopeProvider scopeProvider,
6872
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
69-
IDataTypeConfigurationCache dataTypeReadCache)
73+
IDataTypeConfigurationCache dataTypeReadCache,
74+
ILocalizedTextService localizedTextService)
7075
: base(shortStringHelper, jsonSerializer, ioHelper, attribute)
7176
{
7277
_jsonSerializer = jsonSerializer;
@@ -76,6 +81,34 @@ public MediaPicker3PropertyValueEditor(
7681
_scopeProvider = scopeProvider;
7782
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
7883
_dataTypeReadCache = dataTypeReadCache;
84+
Validators.Add(new MinMaxValidator(jsonSerializer, localizedTextService));
85+
}
86+
87+
[Obsolete("Use non obsoleted constructor instead. Scheduled for removal in v17")]
88+
public MediaPicker3PropertyValueEditor(
89+
IShortStringHelper shortStringHelper,
90+
IJsonSerializer jsonSerializer,
91+
IIOHelper ioHelper,
92+
DataEditorAttribute attribute,
93+
IMediaImportService mediaImportService,
94+
IMediaService mediaService,
95+
ITemporaryFileService temporaryFileService,
96+
IScopeProvider scopeProvider,
97+
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
98+
IDataTypeConfigurationCache dataTypeReadCache)
99+
: this(
100+
shortStringHelper,
101+
jsonSerializer,
102+
ioHelper,
103+
attribute,
104+
mediaImportService,
105+
mediaService,
106+
temporaryFileService,
107+
scopeProvider,
108+
backOfficeSecurityAccessor,
109+
dataTypeReadCache,
110+
StaticServiceProvider.Instance.GetRequiredService<ILocalizedTextService>())
111+
{
79112
}
80113

81114
/// <remarks>
@@ -294,5 +327,61 @@ public void ApplyConfiguration(MediaPicker3Configuration? configuration)
294327
}
295328
}
296329
}
330+
331+
private class MinMaxValidator : IValueValidator
332+
{
333+
private readonly IJsonSerializer _jsonSerializer;
334+
private readonly ILocalizedTextService _localizedTextService;
335+
336+
public MinMaxValidator(IJsonSerializer jsonSerializer, ILocalizedTextService localizedTextService)
337+
{
338+
_jsonSerializer = jsonSerializer;
339+
_localizedTextService = localizedTextService;
340+
}
341+
342+
public IEnumerable<ValidationResult> Validate(
343+
object? value,
344+
string? valueType,
345+
object? dataTypeConfiguration,
346+
PropertyValidationContext validationContext)
347+
{
348+
var validationResults = new List<ValidationResult>();
349+
350+
if (dataTypeConfiguration is not MediaPicker3Configuration mediaPickerConfiguration)
351+
{
352+
return validationResults;
353+
}
354+
355+
if (value is null ||
356+
_jsonSerializer.TryDeserialize(value, out List<MediaWithCropsDto>? mediaWithCropsDtos) is false)
357+
{
358+
return validationResults;
359+
}
360+
361+
if (mediaPickerConfiguration.ValidationLimit.Min is not null
362+
&& mediaWithCropsDtos.Count < mediaPickerConfiguration.ValidationLimit.Min)
363+
{
364+
validationResults.Add(new ValidationResult(
365+
_localizedTextService.Localize(
366+
"validation",
367+
"entriesShort",
368+
new[] { mediaPickerConfiguration.ValidationLimit.Min.ToString(), (mediaPickerConfiguration.ValidationLimit.Min - mediaWithCropsDtos.Count).ToString(), }),
369+
new[] { "validationLimit" }));
370+
}
371+
372+
if (mediaPickerConfiguration.ValidationLimit.Max is not null
373+
&& mediaWithCropsDtos.Count > mediaPickerConfiguration.ValidationLimit.Max)
374+
{
375+
validationResults.Add(new ValidationResult(
376+
_localizedTextService.Localize(
377+
"validation",
378+
"entriesExceed",
379+
new[] { mediaPickerConfiguration.ValidationLimit.Max.ToString(), (mediaWithCropsDtos.Count - mediaPickerConfiguration.ValidationLimit.Max).ToString(), }),
380+
new[] { "validationLimit" }));
381+
}
382+
383+
return validationResults;
384+
}
385+
}
297386
}
298387
}

tests/Umbraco.Tests.UnitTests/Umbraco.Core/PropertyEditors/DataValueReferenceFactoryCollectionTests.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,8 @@ public class DataValueReferenceFactoryCollectionTests
3636
Mock.Of<ITemporaryFileService>(),
3737
Mock.Of<IScopeProvider>(),
3838
Mock.Of<IBackOfficeSecurityAccessor>(),
39-
Mock.Of<IDataTypeConfigurationCache>()));
39+
Mock.Of<IDataTypeConfigurationCache>(),
40+
Mock.Of<ILocalizedTextService>()));
4041

4142
private IIOHelper IOHelper { get; } = Mock.Of<IIOHelper>();
4243

0 commit comments

Comments
 (0)