1+ using System . ComponentModel . DataAnnotations ;
2+ using Microsoft . Extensions . DependencyInjection ;
13using Umbraco . Cms . Core . Cache ;
4+ using Umbraco . Cms . Core . DependencyInjection ;
25using Umbraco . Cms . Core . IO ;
36using Umbraco . Cms . Core . Models ;
47using Umbraco . Cms . Core . Models . Editors ;
58using Umbraco . Cms . Core . Models . TemporaryFile ;
9+ using Umbraco . Cms . Core . Models . Validation ;
610using Umbraco . Cms . Core . PropertyEditors . ValueConverters ;
711using Umbraco . Cms . Core . Security ;
812using 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}
0 commit comments