Fix excessive datatype load times in propertyValueEditors and backoffice mapping (#15731)
* Introduced IDataTypeConfigurationCache * Applied IDataTypeConfigurationCache to Property Editors and display mapping * Invalidate new cache trough DataTypeConfigurationCacheRefresher * Improve IDatatype service to use cached int path when fetching by guid (using idkeymap) --------- Co-authored-by: Sven Geusens <sge@umbraco.dk> Co-authored-by: Ronald Barendse <ronald@barend.se>
This commit is contained in:
@@ -19,6 +19,7 @@
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Sqlite" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore.Design" Version="8.0.1" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Caching.Abstractions" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Abstractions" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.0" />
|
||||
|
||||
51
src/Umbraco.Core/Cache/DataTypeConfigurationCache.cs
Normal file
51
src/Umbraco.Core/Cache/DataTypeConfigurationCache.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using Microsoft.Extensions.Caching.Memory;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Core.Cache;
|
||||
|
||||
/// <summary>
|
||||
/// This cache is a temporary measure to reduce the amount of computational power required to deserialize and initialize <see cref="IDataType" /> when fetched from the main cache/database,
|
||||
/// because datatypes are fetched multiple times troughout a (backoffice content) request with a lot of content (or nested content) and each of these fetches initializes certain fields on the datatypes.
|
||||
/// </summary>
|
||||
internal sealed class DataTypeConfigurationCache : IDataTypeConfigurationCache
|
||||
{
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IMemoryCache _memoryCache;
|
||||
|
||||
public DataTypeConfigurationCache(IDataTypeService dataTypeService, IMemoryCache memoryCache, IIdKeyMap idKeyMap)
|
||||
{
|
||||
_dataTypeService = dataTypeService;
|
||||
_memoryCache = memoryCache;
|
||||
}
|
||||
|
||||
public T? GetConfigurationAs<T>(Guid key)
|
||||
where T : class
|
||||
{
|
||||
var cacheKey = GetCacheKey(key);
|
||||
if (_memoryCache.TryGetValue(cacheKey, out T? configuration) is false)
|
||||
{
|
||||
IDataType? dataType = _dataTypeService.GetDataType(key);
|
||||
configuration = dataType?.ConfigurationAs<T>();
|
||||
|
||||
// Only cache if data type was found (but still cache null configurations)
|
||||
if (dataType is not null)
|
||||
{
|
||||
_memoryCache.Set(cacheKey, configuration);
|
||||
}
|
||||
}
|
||||
|
||||
return configuration;
|
||||
}
|
||||
|
||||
public void ClearCache(IEnumerable<Guid> keys)
|
||||
{
|
||||
foreach (Guid key in keys)
|
||||
{
|
||||
_memoryCache.Remove(GetCacheKey(key));
|
||||
}
|
||||
}
|
||||
|
||||
private static string GetCacheKey(Guid key) => $"DataTypeConfigurationCache_{key}";
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
using Umbraco.Cms.Core.Events;
|
||||
using Umbraco.Cms.Core.Notifications;
|
||||
|
||||
namespace Umbraco.Cms.Core.Cache;
|
||||
|
||||
internal sealed class DataTypeConfigurationCacheRefresher : INotificationHandler<DataTypeCacheRefresherNotification>
|
||||
{
|
||||
private readonly IDataTypeConfigurationCache _dataTypeConfigurationCache;
|
||||
|
||||
public DataTypeConfigurationCacheRefresher(IDataTypeConfigurationCache dataTypeConfigurationCache)
|
||||
=> _dataTypeConfigurationCache = dataTypeConfigurationCache;
|
||||
|
||||
public void Handle(DataTypeCacheRefresherNotification notification)
|
||||
=> _dataTypeConfigurationCache.ClearCache(((DataTypeCacheRefresher.JsonPayload[])notification.MessageObject).Select(x => x.Key));
|
||||
}
|
||||
33
src/Umbraco.Core/Cache/IDataTypeConfigurationCache.cs
Normal file
33
src/Umbraco.Core/Cache/IDataTypeConfigurationCache.cs
Normal file
@@ -0,0 +1,33 @@
|
||||
namespace Umbraco.Cms.Core.Cache;
|
||||
|
||||
/// <summary>
|
||||
/// Represents a cache for <see cref="Umbraco.Cms.Core.Models.IDataType" /> configuration.
|
||||
/// </summary>
|
||||
public interface IDataTypeConfigurationCache
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the data type configuration.
|
||||
/// </summary>
|
||||
/// <param name="key">The data type key.</param>
|
||||
/// <returns>
|
||||
/// The data type configuration.
|
||||
/// </returns>
|
||||
object? GetConfiguration(Guid key) => GetConfigurationAs<object>(key);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the data type configuration as <typeparamref name="T" />.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The data type configuration type.</typeparam>
|
||||
/// <param name="key">The data type key.</param>
|
||||
/// <returns>
|
||||
/// The data type configuration as <typeparamref name="T" />.
|
||||
/// </returns>
|
||||
T? GetConfigurationAs<T>(Guid key)
|
||||
where T : class;
|
||||
|
||||
/// <summary>
|
||||
/// Clears the cache for the specified keys.
|
||||
/// </summary>
|
||||
/// <param name="keys">The keys.</param>
|
||||
void ClearCache(IEnumerable<Guid> keys);
|
||||
}
|
||||
@@ -337,6 +337,10 @@ namespace Umbraco.Cms.Core.DependencyInjection
|
||||
Services.AddUnique<IWebhookLogService, WebhookLogService>();
|
||||
Services.AddUnique<IWebhookLogFactory, WebhookLogFactory>();
|
||||
Services.AddUnique<IWebhookRequestService, WebhookRequestService>();
|
||||
|
||||
// Data type configuration cache
|
||||
Services.AddUnique<IDataTypeConfigurationCache, DataTypeConfigurationCache>();
|
||||
Services.AddNotificationHandler<DataTypeCacheRefresherNotification, DataTypeConfigurationCacheRefresher>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// See LICENSE for more details.
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Dictionary;
|
||||
using Umbraco.Cms.Core.Mapping;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
@@ -17,6 +18,7 @@ namespace Umbraco.Cms.Core.Models.Mapping;
|
||||
internal class ContentPropertyDisplayMapper : ContentPropertyBasicMapper<ContentPropertyDisplay>
|
||||
{
|
||||
private readonly ICultureDictionary _cultureDictionary;
|
||||
private readonly IDataTypeConfigurationCache _dataTypeConfigurationCache;
|
||||
private readonly ILocalizedTextService _textService;
|
||||
|
||||
public ContentPropertyDisplayMapper(
|
||||
@@ -25,10 +27,12 @@ internal class ContentPropertyDisplayMapper : ContentPropertyBasicMapper<Content
|
||||
IEntityService entityService,
|
||||
ILocalizedTextService textService,
|
||||
ILogger<ContentPropertyDisplayMapper> logger,
|
||||
PropertyEditorCollection propertyEditors)
|
||||
PropertyEditorCollection propertyEditors,
|
||||
IDataTypeConfigurationCache dataTypeConfigurationCache)
|
||||
: base(dataTypeService, entityService, logger, propertyEditors)
|
||||
{
|
||||
_cultureDictionary = cultureDictionary;
|
||||
_dataTypeConfigurationCache = dataTypeConfigurationCache;
|
||||
_textService = textService;
|
||||
}
|
||||
|
||||
@@ -38,7 +42,7 @@ internal class ContentPropertyDisplayMapper : ContentPropertyBasicMapper<Content
|
||||
|
||||
var config = originalProp.PropertyType is null
|
||||
? null
|
||||
: DataTypeService.GetDataType(originalProp.PropertyType.DataTypeId)?.Configuration;
|
||||
: _dataTypeConfigurationCache.GetConfiguration(originalProp.PropertyType.DataTypeKey);
|
||||
|
||||
// TODO: IDataValueEditor configuration - general issue
|
||||
// GetValueEditor() returns a non-configured IDataValueEditor
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Dictionary;
|
||||
using Umbraco.Cms.Core.Mapping;
|
||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||
@@ -24,7 +27,8 @@ public class ContentPropertyMapDefinition : IMapDefinition
|
||||
IEntityService entityService,
|
||||
ILocalizedTextService textService,
|
||||
ILoggerFactory loggerFactory,
|
||||
PropertyEditorCollection propertyEditors)
|
||||
PropertyEditorCollection propertyEditors,
|
||||
IDataTypeConfigurationCache dataTypeConfigurationCache)
|
||||
{
|
||||
_contentPropertyBasicConverter = new ContentPropertyBasicMapper<ContentPropertyBasic>(
|
||||
dataTypeService,
|
||||
@@ -42,9 +46,28 @@ public class ContentPropertyMapDefinition : IMapDefinition
|
||||
entityService,
|
||||
textService,
|
||||
loggerFactory.CreateLogger<ContentPropertyDisplayMapper>(),
|
||||
propertyEditors);
|
||||
propertyEditors,
|
||||
dataTypeConfigurationCache);
|
||||
}
|
||||
|
||||
[Obsolete("Please use constructor that takes an IDataTypeConfigurationCache. Will be removed in V14.")]
|
||||
public ContentPropertyMapDefinition(
|
||||
ICultureDictionary cultureDictionary,
|
||||
IDataTypeService dataTypeService,
|
||||
IEntityService entityService,
|
||||
ILocalizedTextService textService,
|
||||
ILoggerFactory loggerFactory,
|
||||
PropertyEditorCollection propertyEditors)
|
||||
: this(
|
||||
cultureDictionary,
|
||||
dataTypeService,
|
||||
entityService,
|
||||
textService,
|
||||
loggerFactory,
|
||||
propertyEditors,
|
||||
StaticServiceProvider.Instance.GetRequiredService<IDataTypeConfigurationCache>())
|
||||
{ }
|
||||
|
||||
public void DefineMaps(IUmbracoMapper mapper)
|
||||
{
|
||||
mapper.Define<PropertyGroup, Tab<ContentPropertyDisplay>>(
|
||||
|
||||
@@ -14,7 +14,6 @@ using Umbraco.Cms.Core.Scoping;
|
||||
using Umbraco.Cms.Core.Serialization;
|
||||
using Umbraco.Cms.Core.Strings;
|
||||
using Umbraco.Extensions;
|
||||
using static System.Formats.Asn1.AsnWriter;
|
||||
|
||||
namespace Umbraco.Cms.Core.Services.Implement
|
||||
{
|
||||
@@ -30,28 +29,25 @@ namespace Umbraco.Cms.Core.Services.Implement
|
||||
private readonly IAuditRepository _auditRepository;
|
||||
private readonly IEntityRepository _entityRepository;
|
||||
private readonly IIOHelper _ioHelper;
|
||||
private readonly ILocalizedTextService _localizedTextService;
|
||||
private readonly ILocalizationService _localizationService;
|
||||
private readonly IShortStringHelper _shortStringHelper;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly IEditorConfigurationParser _editorConfigurationParser;
|
||||
private readonly Lazy<IIdKeyMap> _idKeyMap;
|
||||
|
||||
[Obsolete("Please use constructor that takes an IEditorConfigurationParser. Will be removed in V13.")]
|
||||
[Obsolete("Please use constructor that takes an IEditorConfigurationParser. Will be removed in V14.")]
|
||||
public DataTypeService(
|
||||
IDataValueEditorFactory dataValueEditorFactory,
|
||||
ICoreScopeProvider provider,
|
||||
ILoggerFactory loggerFactory,
|
||||
IEventMessagesFactory eventMessagesFactory,
|
||||
IDataTypeRepository dataTypeRepository,
|
||||
IDataTypeContainerRepository dataTypeContainerRepository,
|
||||
IAuditRepository auditRepository,
|
||||
IEntityRepository entityRepository,
|
||||
IContentTypeRepository contentTypeRepository,
|
||||
IIOHelper ioHelper,
|
||||
ILocalizedTextService localizedTextService,
|
||||
ILocalizationService localizationService,
|
||||
IShortStringHelper shortStringHelper,
|
||||
IJsonSerializer jsonSerializer)
|
||||
IDataValueEditorFactory dataValueEditorFactory,
|
||||
ICoreScopeProvider provider,
|
||||
ILoggerFactory loggerFactory,
|
||||
IEventMessagesFactory eventMessagesFactory,
|
||||
IDataTypeRepository dataTypeRepository,
|
||||
IDataTypeContainerRepository dataTypeContainerRepository,
|
||||
IAuditRepository auditRepository,
|
||||
IEntityRepository entityRepository,
|
||||
IContentTypeRepository contentTypeRepository,
|
||||
IIOHelper ioHelper,
|
||||
ILocalizedTextService localizedTextService,
|
||||
ILocalizationService localizationService,
|
||||
IShortStringHelper shortStringHelper,
|
||||
IJsonSerializer jsonSerializer)
|
||||
: this(
|
||||
dataValueEditorFactory,
|
||||
provider,
|
||||
@@ -68,20 +64,9 @@ namespace Umbraco.Cms.Core.Services.Implement
|
||||
shortStringHelper,
|
||||
jsonSerializer,
|
||||
StaticServiceProvider.Instance.GetRequiredService<IEditorConfigurationParser>())
|
||||
{
|
||||
_dataValueEditorFactory = dataValueEditorFactory;
|
||||
_dataTypeRepository = dataTypeRepository;
|
||||
_dataTypeContainerRepository = dataTypeContainerRepository;
|
||||
_auditRepository = auditRepository;
|
||||
_entityRepository = entityRepository;
|
||||
_contentTypeRepository = contentTypeRepository;
|
||||
_ioHelper = ioHelper;
|
||||
_localizedTextService = localizedTextService;
|
||||
_localizationService = localizationService;
|
||||
_shortStringHelper = shortStringHelper;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
}
|
||||
{ }
|
||||
|
||||
[Obsolete("Please use constructor that takes an IIdKeyMap. Will be removed in V14.")]
|
||||
public DataTypeService(
|
||||
IDataValueEditorFactory dataValueEditorFactory,
|
||||
ICoreScopeProvider provider,
|
||||
@@ -98,6 +83,43 @@ namespace Umbraco.Cms.Core.Services.Implement
|
||||
IShortStringHelper shortStringHelper,
|
||||
IJsonSerializer jsonSerializer,
|
||||
IEditorConfigurationParser editorConfigurationParser)
|
||||
: this(
|
||||
dataValueEditorFactory,
|
||||
provider,
|
||||
loggerFactory,
|
||||
eventMessagesFactory,
|
||||
dataTypeRepository,
|
||||
dataTypeContainerRepository,
|
||||
auditRepository,
|
||||
entityRepository,
|
||||
contentTypeRepository,
|
||||
ioHelper,
|
||||
localizedTextService,
|
||||
localizationService,
|
||||
shortStringHelper,
|
||||
jsonSerializer,
|
||||
editorConfigurationParser,
|
||||
StaticServiceProvider.Instance.GetRequiredService<Lazy<IIdKeyMap>>())
|
||||
{ }
|
||||
|
||||
// TODO: Unused parameters can be removed once the obsolete constructors are removed (kept to avoid ambiguous constructors)
|
||||
public DataTypeService(
|
||||
IDataValueEditorFactory dataValueEditorFactory,
|
||||
ICoreScopeProvider provider,
|
||||
ILoggerFactory loggerFactory,
|
||||
IEventMessagesFactory eventMessagesFactory,
|
||||
IDataTypeRepository dataTypeRepository,
|
||||
IDataTypeContainerRepository dataTypeContainerRepository,
|
||||
IAuditRepository auditRepository,
|
||||
IEntityRepository entityRepository,
|
||||
IContentTypeRepository contentTypeRepository,
|
||||
IIOHelper ioHelper,
|
||||
ILocalizedTextService localizedTextService,
|
||||
ILocalizationService localizationService,
|
||||
IShortStringHelper shortStringHelper,
|
||||
IJsonSerializer jsonSerializer,
|
||||
IEditorConfigurationParser editorConfigurationParser,
|
||||
Lazy<IIdKeyMap> idKeyMap)
|
||||
: base(provider, loggerFactory, eventMessagesFactory)
|
||||
{
|
||||
_dataValueEditorFactory = dataValueEditorFactory;
|
||||
@@ -107,11 +129,8 @@ namespace Umbraco.Cms.Core.Services.Implement
|
||||
_entityRepository = entityRepository;
|
||||
_contentTypeRepository = contentTypeRepository;
|
||||
_ioHelper = ioHelper;
|
||||
_localizedTextService = localizedTextService;
|
||||
_localizationService = localizationService;
|
||||
_shortStringHelper = shortStringHelper;
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_editorConfigurationParser = editorConfigurationParser;
|
||||
_idKeyMap = idKeyMap;
|
||||
}
|
||||
|
||||
#region Containers
|
||||
@@ -336,13 +355,12 @@ namespace Umbraco.Cms.Core.Services.Implement
|
||||
/// <param name="id">Unique guid Id of the DataType</param>
|
||||
/// <returns><see cref="IDataType"/></returns>
|
||||
public IDataType? GetDataType(Guid id)
|
||||
{
|
||||
using ICoreScope scope = ScopeProvider.CreateCoreScope(autoComplete: true);
|
||||
IQuery<IDataType> query = Query<IDataType>().Where(x => x.Key == id);
|
||||
IDataType? dataType = _dataTypeRepository.Get(query).FirstOrDefault();
|
||||
ConvertMissingEditorOfDataTypeToLabel(dataType);
|
||||
return dataType;
|
||||
}
|
||||
// Lookup the integer ID, so the data type can be retrieved from the repository cache
|
||||
=>_idKeyMap.Value.GetIdForKey(id, UmbracoObjectTypes.DataType) switch
|
||||
{
|
||||
{ Success: false } => null,
|
||||
{ Result: var intId } => GetDataType(intId),
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Gets a <see cref="IDataType"/> by its control Id
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Caching.Abstractions" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Abstractions" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Embedded" />
|
||||
<PackageReference Include="Microsoft.Extensions.FileProviders.Physical" />
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.Blocks;
|
||||
@@ -16,7 +17,7 @@ namespace Umbraco.Cms.Core.PropertyEditors;
|
||||
internal abstract class BlockEditorPropertyValueEditor : BlockValuePropertyValueEditorBase
|
||||
{
|
||||
private BlockEditorValues? _blockEditorValues;
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IDataTypeConfigurationCache _dataTypeConfigurationCache;
|
||||
private readonly PropertyEditorCollection _propertyEditors;
|
||||
private readonly DataValueReferenceFactoryCollection _dataValueReferenceFactories;
|
||||
private readonly ILogger<BlockEditorPropertyValueEditor> _logger;
|
||||
@@ -25,17 +26,17 @@ internal abstract class BlockEditorPropertyValueEditor : BlockValuePropertyValue
|
||||
DataEditorAttribute attribute,
|
||||
PropertyEditorCollection propertyEditors,
|
||||
DataValueReferenceFactoryCollection dataValueReferenceFactories,
|
||||
IDataTypeService dataTypeService,
|
||||
IDataTypeConfigurationCache dataTypeConfigurationCache,
|
||||
ILocalizedTextService textService,
|
||||
ILogger<BlockEditorPropertyValueEditor> logger,
|
||||
IShortStringHelper shortStringHelper,
|
||||
IJsonSerializer jsonSerializer,
|
||||
IIOHelper ioHelper)
|
||||
: base(attribute, propertyEditors, dataTypeService, textService, logger, shortStringHelper, jsonSerializer, ioHelper, dataValueReferenceFactories)
|
||||
: base(attribute, propertyEditors, dataTypeConfigurationCache, textService, logger, shortStringHelper, jsonSerializer, ioHelper, dataValueReferenceFactories)
|
||||
{
|
||||
_propertyEditors = propertyEditors;
|
||||
_dataValueReferenceFactories = dataValueReferenceFactories;
|
||||
_dataTypeService = dataTypeService;
|
||||
_dataTypeConfigurationCache = dataTypeConfigurationCache;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
@@ -75,7 +76,7 @@ internal abstract class BlockEditorPropertyValueEditor : BlockValuePropertyValue
|
||||
continue;
|
||||
}
|
||||
|
||||
object? configuration = _dataTypeService.GetDataType(propertyValue.PropertyType.DataTypeKey)?.Configuration;
|
||||
object? configuration = _dataTypeConfigurationCache.GetConfiguration(propertyValue.PropertyType.DataTypeKey);
|
||||
foreach (ITag tag in dataValueTags.GetTags(propertyValue.Value, configuration, languageId))
|
||||
{
|
||||
yield return tag;
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.Blocks;
|
||||
@@ -51,7 +52,7 @@ public abstract class BlockGridPropertyEditorBase : DataEditor
|
||||
DataEditorAttribute attribute,
|
||||
PropertyEditorCollection propertyEditors,
|
||||
DataValueReferenceFactoryCollection dataValueReferenceFactories,
|
||||
IDataTypeService dataTypeService,
|
||||
IDataTypeConfigurationCache dataTypeConfigurationCache,
|
||||
ILocalizedTextService textService,
|
||||
ILogger<BlockEditorPropertyValueEditor> logger,
|
||||
IShortStringHelper shortStringHelper,
|
||||
@@ -59,7 +60,7 @@ public abstract class BlockGridPropertyEditorBase : DataEditor
|
||||
IIOHelper ioHelper,
|
||||
IContentTypeService contentTypeService,
|
||||
IPropertyValidationService propertyValidationService)
|
||||
: base(attribute, propertyEditors, dataValueReferenceFactories, dataTypeService, textService, logger, shortStringHelper, jsonSerializer, ioHelper)
|
||||
: base(attribute, propertyEditors, dataValueReferenceFactories, dataTypeConfigurationCache, textService, logger, shortStringHelper, jsonSerializer, ioHelper)
|
||||
{
|
||||
BlockEditorValues = new BlockEditorValues(new BlockGridEditorDataConverter(jsonSerializer), contentTypeService, logger);
|
||||
Validators.Add(new BlockEditorValidator(propertyValidationService, BlockEditorValues, contentTypeService));
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using System.ComponentModel.DataAnnotations;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.Blocks;
|
||||
@@ -53,7 +54,7 @@ public abstract class BlockListPropertyEditorBase : DataEditor
|
||||
BlockEditorDataConverter blockEditorDataConverter,
|
||||
PropertyEditorCollection propertyEditors,
|
||||
DataValueReferenceFactoryCollection dataValueReferenceFactories,
|
||||
IDataTypeService dataTypeService,
|
||||
IDataTypeConfigurationCache dataTypeConfigurationCache,
|
||||
IContentTypeService contentTypeService,
|
||||
ILocalizedTextService textService,
|
||||
ILogger<BlockEditorPropertyValueEditor> logger,
|
||||
@@ -61,7 +62,7 @@ public abstract class BlockListPropertyEditorBase : DataEditor
|
||||
IJsonSerializer jsonSerializer,
|
||||
IIOHelper ioHelper,
|
||||
IPropertyValidationService propertyValidationService) :
|
||||
base(attribute, propertyEditors, dataValueReferenceFactories,dataTypeService, textService, logger, shortStringHelper, jsonSerializer, ioHelper)
|
||||
base(attribute, propertyEditors, dataValueReferenceFactories, dataTypeConfigurationCache, textService, logger, shortStringHelper, jsonSerializer, ioHelper)
|
||||
{
|
||||
BlockEditorValues = new BlockEditorValues(blockEditorDataConverter, contentTypeService, logger);
|
||||
Validators.Add(new BlockEditorValidator(propertyValidationService, BlockEditorValues, contentTypeService));
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
using Umbraco.Cms.Core.Models.Blocks;
|
||||
@@ -11,7 +12,7 @@ namespace Umbraco.Cms.Core.PropertyEditors;
|
||||
|
||||
internal abstract class BlockValuePropertyValueEditorBase : DataValueEditor, IDataValueReference, IDataValueTags
|
||||
{
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IDataTypeConfigurationCache _dataTypeConfigurationCache;
|
||||
private readonly PropertyEditorCollection _propertyEditors;
|
||||
private readonly ILogger _logger;
|
||||
private readonly DataValueReferenceFactoryCollection _dataValueReferenceFactoryCollection;
|
||||
@@ -19,7 +20,7 @@ internal abstract class BlockValuePropertyValueEditorBase : DataValueEditor, IDa
|
||||
protected BlockValuePropertyValueEditorBase(
|
||||
DataEditorAttribute attribute,
|
||||
PropertyEditorCollection propertyEditors,
|
||||
IDataTypeService dataTypeService,
|
||||
IDataTypeConfigurationCache dataTypeConfigurationCache,
|
||||
ILocalizedTextService textService,
|
||||
ILogger logger,
|
||||
IShortStringHelper shortStringHelper,
|
||||
@@ -29,7 +30,7 @@ internal abstract class BlockValuePropertyValueEditorBase : DataValueEditor, IDa
|
||||
: base(textService, shortStringHelper, jsonSerializer, ioHelper, attribute)
|
||||
{
|
||||
_propertyEditors = propertyEditors;
|
||||
_dataTypeService = dataTypeService;
|
||||
_dataTypeConfigurationCache = dataTypeConfigurationCache;
|
||||
_logger = logger;
|
||||
_dataValueReferenceFactoryCollection = dataValueReferenceFactoryCollection;
|
||||
}
|
||||
@@ -76,6 +77,7 @@ internal abstract class BlockValuePropertyValueEditorBase : DataValueEditor, IDa
|
||||
protected IEnumerable<ITag> GetBlockValueTags(BlockValue blockValue, int? languageId)
|
||||
{
|
||||
var result = new List<ITag>();
|
||||
|
||||
// loop through all content and settings data
|
||||
foreach (BlockItemData row in blockValue.ContentData.Concat(blockValue.SettingsData))
|
||||
{
|
||||
@@ -89,7 +91,7 @@ internal abstract class BlockValuePropertyValueEditorBase : DataValueEditor, IDa
|
||||
continue;
|
||||
}
|
||||
|
||||
object? configuration = _dataTypeService.GetDataType(prop.Value.PropertyType.DataTypeKey)?.Configuration;
|
||||
object? configuration = _dataTypeConfigurationCache.GetConfiguration(prop.Value.PropertyType.DataTypeKey);
|
||||
|
||||
result.AddRange(tagsProvider.GetTags(prop.Value.Value, configuration, languageId));
|
||||
}
|
||||
@@ -112,7 +114,7 @@ internal abstract class BlockValuePropertyValueEditorBase : DataValueEditor, IDa
|
||||
|
||||
private void MapBlockItemDataToEditor(IProperty property, List<BlockItemData> items)
|
||||
{
|
||||
var valEditors = new Dictionary<int, IDataValueEditor>();
|
||||
var valEditors = new Dictionary<Guid, IDataValueEditor>();
|
||||
|
||||
foreach (BlockItemData row in items)
|
||||
{
|
||||
@@ -134,25 +136,13 @@ internal abstract class BlockValuePropertyValueEditorBase : DataValueEditor, IDa
|
||||
continue;
|
||||
}
|
||||
|
||||
IDataType? dataType = _dataTypeService.GetDataType(prop.Value.PropertyType.DataTypeId);
|
||||
if (dataType == null)
|
||||
Guid dataTypeKey = prop.Value.PropertyType.DataTypeKey;
|
||||
if (!valEditors.TryGetValue(dataTypeKey, out IDataValueEditor? valEditor))
|
||||
{
|
||||
// deal with weird situations by ignoring them (no comment)
|
||||
row.PropertyValues.Remove(prop.Key);
|
||||
_logger.LogWarning(
|
||||
"ToEditor removed property value {PropertyKey} in row {RowId} for property type {PropertyTypeAlias}",
|
||||
prop.Key,
|
||||
row.Key,
|
||||
property.PropertyType.Alias);
|
||||
continue;
|
||||
}
|
||||
var configuration = _dataTypeConfigurationCache.GetConfiguration(dataTypeKey);
|
||||
valEditor = propEditor.GetValueEditor(configuration);
|
||||
|
||||
if (!valEditors.TryGetValue(dataType.Id, out IDataValueEditor? valEditor))
|
||||
{
|
||||
var tempConfig = dataType.Configuration;
|
||||
valEditor = propEditor.GetValueEditor(tempConfig);
|
||||
|
||||
valEditors.Add(dataType.Id, valEditor);
|
||||
valEditors.Add(dataTypeKey, valEditor);
|
||||
}
|
||||
|
||||
var convValue = valEditor.ToEditor(tempProp);
|
||||
@@ -170,7 +160,7 @@ internal abstract class BlockValuePropertyValueEditorBase : DataValueEditor, IDa
|
||||
foreach (KeyValuePair<string, BlockItemData.BlockPropertyValue> prop in row.PropertyValues)
|
||||
{
|
||||
// Fetch the property types prevalue
|
||||
var propConfiguration = _dataTypeService.GetDataType(prop.Value.PropertyType.DataTypeId)?.Configuration;
|
||||
var configuration = _dataTypeConfigurationCache.GetConfiguration(prop.Value.PropertyType.DataTypeKey);
|
||||
|
||||
// Lookup the property editor
|
||||
IDataEditor? propEditor = _propertyEditors[prop.Value.PropertyType.PropertyEditorAlias];
|
||||
@@ -180,7 +170,7 @@ internal abstract class BlockValuePropertyValueEditorBase : DataValueEditor, IDa
|
||||
}
|
||||
|
||||
// Create a fake content property data object
|
||||
var contentPropData = new ContentPropertyData(prop.Value.Value, propConfiguration);
|
||||
var contentPropData = new ContentPropertyData(prop.Value.Value, configuration);
|
||||
|
||||
// Get the property editor to do it's conversion
|
||||
var newValue = propEditor.GetValueEditor().FromEditor(contentPropData, prop.Value.Value);
|
||||
|
||||
@@ -5,6 +5,7 @@ using Microsoft.Extensions.Logging;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
@@ -24,7 +25,7 @@ namespace Umbraco.Cms.Core.PropertyEditors;
|
||||
/// </summary>
|
||||
internal class ImageCropperPropertyValueEditor : DataValueEditor // TODO: core vs web?
|
||||
{
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IDataTypeConfigurationCache _dataTypeConfigurationCache;
|
||||
private readonly IFileStreamSecurityValidator _fileStreamSecurityValidator;
|
||||
private readonly ILogger<ImageCropperPropertyValueEditor> _logger;
|
||||
private readonly MediaFileManager _mediaFileManager;
|
||||
@@ -39,14 +40,14 @@ internal class ImageCropperPropertyValueEditor : DataValueEditor // TODO: core v
|
||||
IOptionsMonitor<ContentSettings> contentSettings,
|
||||
IJsonSerializer jsonSerializer,
|
||||
IIOHelper ioHelper,
|
||||
IDataTypeService dataTypeService,
|
||||
IDataTypeConfigurationCache dataTypeConfigurationCache,
|
||||
IFileStreamSecurityValidator fileStreamSecurityValidator)
|
||||
: base(localizedTextService, shortStringHelper, jsonSerializer, ioHelper, attribute)
|
||||
{
|
||||
_logger = logger ?? throw new ArgumentNullException(nameof(logger));
|
||||
_mediaFileManager = mediaFileSystem ?? throw new ArgumentNullException(nameof(mediaFileSystem));
|
||||
_contentSettings = contentSettings.CurrentValue;
|
||||
_dataTypeService = dataTypeService;
|
||||
_dataTypeConfigurationCache = dataTypeConfigurationCache;
|
||||
_fileStreamSecurityValidator = fileStreamSecurityValidator;
|
||||
contentSettings.OnChange(x => _contentSettings = x);
|
||||
}
|
||||
@@ -73,10 +74,10 @@ internal class ImageCropperPropertyValueEditor : DataValueEditor // TODO: core v
|
||||
value = new ImageCropperValue { Src = val.ToString() };
|
||||
}
|
||||
|
||||
IDataType? dataType = _dataTypeService.GetDataType(property.PropertyType.DataTypeId);
|
||||
if (dataType?.Configuration != null)
|
||||
var configuration = _dataTypeConfigurationCache.GetConfigurationAs<ImageCropperConfiguration>(property.PropertyType.DataTypeKey);
|
||||
if (configuration is not null)
|
||||
{
|
||||
value?.ApplyConfiguration(dataType.ConfigurationAs<ImageCropperConfiguration>());
|
||||
value?.ApplyConfiguration(configuration);
|
||||
}
|
||||
|
||||
return value;
|
||||
@@ -216,8 +217,7 @@ internal class ImageCropperPropertyValueEditor : DataValueEditor // TODO: core v
|
||||
}
|
||||
|
||||
// more magic here ;-(
|
||||
ImageCropperConfiguration? configuration = _dataTypeService.GetDataType(propertyType.DataTypeId)
|
||||
?.ConfigurationAs<ImageCropperConfiguration>();
|
||||
ImageCropperConfiguration? configuration = _dataTypeConfigurationCache.GetConfigurationAs<ImageCropperConfiguration>(propertyType.DataTypeKey);
|
||||
ImageCropperConfiguration.Crop[] crops = configuration?.Crops ?? Array.Empty<ImageCropperConfiguration.Crop>();
|
||||
|
||||
return JsonConvert.SerializeObject(
|
||||
|
||||
@@ -3,6 +3,7 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
@@ -72,7 +73,7 @@ public class MediaPicker3PropertyEditor : DataEditor
|
||||
|
||||
internal class MediaPicker3PropertyValueEditor : DataValueEditor, IDataValueReference
|
||||
{
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IDataTypeConfigurationCache _dataTypeReadCache;
|
||||
private readonly IJsonSerializer _jsonSerializer;
|
||||
private readonly ITemporaryMediaService _temporaryMediaService;
|
||||
|
||||
@@ -83,12 +84,12 @@ public class MediaPicker3PropertyEditor : DataEditor
|
||||
IJsonSerializer jsonSerializer,
|
||||
IIOHelper ioHelper,
|
||||
DataEditorAttribute attribute,
|
||||
IDataTypeService dataTypeService,
|
||||
IDataTypeConfigurationCache dataTypeReadCache,
|
||||
ITemporaryMediaService temporaryMediaService)
|
||||
: base(localizedTextService, shortStringHelper, jsonSerializer, ioHelper, attribute)
|
||||
{
|
||||
_jsonSerializer = jsonSerializer;
|
||||
_dataTypeService = dataTypeService;
|
||||
_dataTypeReadCache = dataTypeReadCache;
|
||||
_temporaryMediaService = temporaryMediaService;
|
||||
}
|
||||
|
||||
@@ -110,11 +111,9 @@ public class MediaPicker3PropertyEditor : DataEditor
|
||||
|
||||
var dtos = Deserialize(_jsonSerializer, value).ToList();
|
||||
|
||||
IDataType? dataType = _dataTypeService.GetDataType(property.PropertyType.DataTypeId);
|
||||
if (dataType?.Configuration != null)
|
||||
var configuration = _dataTypeReadCache.GetConfigurationAs<MediaPicker3Configuration>(property.PropertyType.DataTypeKey);
|
||||
if (configuration is not null)
|
||||
{
|
||||
MediaPicker3Configuration? configuration = dataType.ConfigurationAs<MediaPicker3Configuration>();
|
||||
|
||||
foreach (MediaWithCropsDto dto in dtos)
|
||||
{
|
||||
dto.ApplyConfiguration(configuration);
|
||||
|
||||
@@ -5,6 +5,7 @@ using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
using Umbraco.Cms.Core.Models;
|
||||
@@ -90,14 +91,14 @@ public class NestedContentPropertyEditor : DataEditor
|
||||
|
||||
internal class NestedContentPropertyValueEditor : DataValueEditor, IDataValueReference, IDataValueTags
|
||||
{
|
||||
private readonly IDataTypeService _dataTypeService;
|
||||
private readonly IDataTypeConfigurationCache _dataTypeReadCache;
|
||||
private readonly PropertyEditorCollection _propertyEditors;
|
||||
private readonly DataValueReferenceFactoryCollection _dataValueReferenceFactories;
|
||||
private readonly ILogger<NestedContentPropertyEditor> _logger;
|
||||
private readonly NestedContentValues _nestedContentValues;
|
||||
|
||||
public NestedContentPropertyValueEditor(
|
||||
IDataTypeService dataTypeService,
|
||||
IDataTypeConfigurationCache dataTypeReadCache,
|
||||
ILocalizedTextService localizedTextService,
|
||||
IContentTypeService contentTypeService,
|
||||
IShortStringHelper shortStringHelper,
|
||||
@@ -110,7 +111,7 @@ public class NestedContentPropertyEditor : DataEditor
|
||||
IPropertyValidationService propertyValidationService)
|
||||
: base(localizedTextService, shortStringHelper, jsonSerializer, ioHelper, attribute)
|
||||
{
|
||||
_dataTypeService = dataTypeService;
|
||||
_dataTypeReadCache = dataTypeReadCache;
|
||||
_propertyEditors = propertyEditors;
|
||||
_dataValueReferenceFactories = dataValueReferenceFactories;
|
||||
_logger = logger;
|
||||
@@ -173,7 +174,7 @@ public class NestedContentPropertyEditor : DataEditor
|
||||
continue;
|
||||
}
|
||||
|
||||
object? configuration = _dataTypeService.GetDataType(propertyValue.PropertyType.DataTypeKey)?.Configuration;
|
||||
object? configuration = _dataTypeReadCache.GetConfiguration(propertyValue.PropertyType.DataTypeKey);
|
||||
foreach (ITag tag in dataValueTags.GetTags(propertyValue.Value, configuration, languageId))
|
||||
{
|
||||
yield return tag;
|
||||
@@ -188,8 +189,7 @@ public class NestedContentPropertyEditor : DataEditor
|
||||
|
||||
public override string ConvertDbToString(IPropertyType propertyType, object? propertyValue)
|
||||
{
|
||||
IReadOnlyList<NestedContentValues.NestedContentRowValue> rows =
|
||||
_nestedContentValues.GetPropertyValues(propertyValue);
|
||||
IReadOnlyList<NestedContentValues.NestedContentRowValue> rows = _nestedContentValues.GetPropertyValues(propertyValue);
|
||||
|
||||
if (rows.Count == 0)
|
||||
{
|
||||
@@ -198,8 +198,7 @@ public class NestedContentPropertyEditor : DataEditor
|
||||
|
||||
foreach (NestedContentValues.NestedContentRowValue row in rows.ToList())
|
||||
{
|
||||
foreach (KeyValuePair<string, NestedContentValues.NestedContentPropertyValue> prop in row.PropertyValues
|
||||
.ToList())
|
||||
foreach (KeyValuePair<string, NestedContentValues.NestedContentPropertyValue> prop in row.PropertyValues.ToList())
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -210,9 +209,8 @@ public class NestedContentPropertyEditor : DataEditor
|
||||
continue;
|
||||
}
|
||||
|
||||
var tempConfig = _dataTypeService.GetDataType(prop.Value.PropertyType.DataTypeId)
|
||||
?.Configuration;
|
||||
IDataValueEditor valEditor = propEditor.GetValueEditor(tempConfig);
|
||||
var configuration = _dataTypeReadCache.GetConfiguration(prop.Value.PropertyType.DataTypeKey);
|
||||
IDataValueEditor valEditor = propEditor.GetValueEditor(configuration);
|
||||
var convValue = valEditor.ConvertDbToString(prop.Value.PropertyType, prop.Value.Value);
|
||||
|
||||
// update the raw value since this is what will get serialized out
|
||||
@@ -246,7 +244,7 @@ public class NestedContentPropertyEditor : DataEditor
|
||||
public override object ToEditor(IProperty property, string? culture = null, string? segment = null)
|
||||
{
|
||||
var val = property.GetValue(culture, segment);
|
||||
var valEditors = new Dictionary<int, IDataValueEditor>();
|
||||
var valEditors = new Dictionary<Guid, IDataValueEditor>();
|
||||
|
||||
IReadOnlyList<NestedContentValues.NestedContentRowValue> rows = _nestedContentValues.GetPropertyValues(val);
|
||||
|
||||
@@ -278,13 +276,13 @@ public class NestedContentPropertyEditor : DataEditor
|
||||
continue;
|
||||
}
|
||||
|
||||
var dataTypeId = prop.Value.PropertyType.DataTypeId;
|
||||
if (!valEditors.TryGetValue(dataTypeId, out IDataValueEditor? valEditor))
|
||||
Guid dataTypeKey = prop.Value.PropertyType.DataTypeKey;
|
||||
if (!valEditors.TryGetValue(dataTypeKey, out IDataValueEditor? valEditor))
|
||||
{
|
||||
var tempConfig = _dataTypeService.GetDataType(dataTypeId)?.Configuration;
|
||||
var tempConfig = _dataTypeReadCache.GetConfiguration(dataTypeKey);
|
||||
valEditor = propEditor.GetValueEditor(tempConfig);
|
||||
|
||||
valEditors.Add(dataTypeId, valEditor);
|
||||
valEditors.Add(dataTypeKey, valEditor);
|
||||
}
|
||||
|
||||
var convValue = valEditor.ToEditor(tempProp);
|
||||
@@ -318,8 +316,7 @@ public class NestedContentPropertyEditor : DataEditor
|
||||
return null;
|
||||
}
|
||||
|
||||
IReadOnlyList<NestedContentValues.NestedContentRowValue> rows =
|
||||
_nestedContentValues.GetPropertyValues(editorValue.Value);
|
||||
IReadOnlyList<NestedContentValues.NestedContentRowValue> rows = _nestedContentValues.GetPropertyValues(editorValue.Value);
|
||||
|
||||
if (rows.Count == 0)
|
||||
{
|
||||
@@ -328,12 +325,10 @@ public class NestedContentPropertyEditor : DataEditor
|
||||
|
||||
foreach (NestedContentValues.NestedContentRowValue row in rows.ToList())
|
||||
{
|
||||
foreach (KeyValuePair<string, NestedContentValues.NestedContentPropertyValue> prop in row.PropertyValues
|
||||
.ToList())
|
||||
foreach (KeyValuePair<string, NestedContentValues.NestedContentPropertyValue> prop in row.PropertyValues.ToList())
|
||||
{
|
||||
// Fetch the property types prevalue
|
||||
var propConfiguration =
|
||||
_dataTypeService.GetDataType(prop.Value.PropertyType.DataTypeId)?.Configuration;
|
||||
var propConfiguration = _dataTypeReadCache.GetConfiguration(prop.Value.PropertyType.DataTypeKey);
|
||||
|
||||
// Lookup the property editor
|
||||
IDataEditor? propEditor = _propertyEditors[prop.Value.PropertyType.PropertyEditorAlias];
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
using Umbraco.Cms.Core.Media;
|
||||
@@ -176,7 +177,7 @@ public class RichTextPropertyEditor : DataEditor
|
||||
public RichTextPropertyValueEditor(
|
||||
DataEditorAttribute attribute,
|
||||
PropertyEditorCollection propertyEditors,
|
||||
IDataTypeService dataTypeService,
|
||||
IDataTypeConfigurationCache dataTypeReadCache,
|
||||
ILogger<RichTextPropertyValueEditor> logger,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
ILocalizedTextService localizedTextService,
|
||||
@@ -191,7 +192,7 @@ public class RichTextPropertyEditor : DataEditor
|
||||
IContentTypeService contentTypeService,
|
||||
IPropertyValidationService propertyValidationService,
|
||||
DataValueReferenceFactoryCollection dataValueReferenceFactoryCollection)
|
||||
: base(attribute, propertyEditors, dataTypeService, localizedTextService, logger, shortStringHelper, jsonSerializer, ioHelper, dataValueReferenceFactoryCollection)
|
||||
: base(attribute, propertyEditors, dataTypeReadCache, localizedTextService, logger, shortStringHelper, jsonSerializer, ioHelper, dataValueReferenceFactoryCollection)
|
||||
{
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
_imageSourceParser = imageSourceParser;
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
using Microsoft.Extensions.Logging;
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
using Umbraco.Cms.Core.Models.Blocks;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
@@ -42,7 +43,7 @@ public class DataValueEditorReuseTests
|
||||
new BlockListEditorDataConverter(),
|
||||
_propertyEditorCollection,
|
||||
_dataValueReferenceFactories,
|
||||
Mock.Of<IDataTypeService>(),
|
||||
Mock.Of<IDataTypeConfigurationCache>(),
|
||||
Mock.Of<IContentTypeService>(),
|
||||
Mock.Of<ILocalizedTextService>(),
|
||||
Mock.Of<ILogger<BlockListPropertyEditorBase.BlockListEditorPropertyValueEditor>>(),
|
||||
|
||||
Reference in New Issue
Block a user