Files
Umbraco-CMS/src/Umbraco.Infrastructure/PropertyEditors/BlockListPropertyEditorBase.cs
Bjarke Berg 0aaac78cfa A bunch of minor performance optimizations (#16335)
* Do not execute query if no macros found

* Request cache the permission lookup

* Unbreak change by adding obsolete ctor

* Clean up

* Wrap indexing for delivery API in a scope

* Do not ask options every time for the timeout, instead listen for updates

* Lookup content types once instead of one by one

* Use TryGetValue instead

* Do a distinct on user ids before building index, to avoid issue with more than 2100 parameters

* Don't map ContentDto (it's unused)

* Introduce request bound block editor element cache

---------

Co-authored-by: kjac <kja@umbraco.dk>
2024-06-03 11:23:25 +02:00

100 lines
4.4 KiB
C#

using System.ComponentModel.DataAnnotations;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Logging;
using Umbraco.Cms.Core.Cache;
using Umbraco.Cms.Core.Cache.PropertyEditors;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Blocks;
using Umbraco.Cms.Core.Serialization;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Core.Strings;
using Umbraco.Cms.Web.Common.DependencyInjection;
namespace Umbraco.Cms.Core.PropertyEditors;
/// <summary>
/// Abstract base class for block list based editors.
/// </summary>
public abstract class BlockListPropertyEditorBase : DataEditor
{
private readonly IBlockValuePropertyIndexValueFactory _blockValuePropertyIndexValueFactory;
[Obsolete("Use non-obsoleted ctor. This will be removed in Umbraco 13.")]
protected BlockListPropertyEditorBase(IDataValueEditorFactory dataValueEditorFactory)
: this(dataValueEditorFactory, StaticServiceProvider.Instance.GetRequiredService<IBlockValuePropertyIndexValueFactory>())
{
}
protected BlockListPropertyEditorBase(IDataValueEditorFactory dataValueEditorFactory, IBlockValuePropertyIndexValueFactory blockValuePropertyIndexValueFactory)
: base(dataValueEditorFactory)
{
_blockValuePropertyIndexValueFactory = blockValuePropertyIndexValueFactory;
SupportsReadOnly = true;
}
public override IPropertyIndexValueFactory PropertyIndexValueFactory => _blockValuePropertyIndexValueFactory;
#region Value Editor
/// <summary>
/// Instantiates a new <see cref="BlockEditorDataConverter"/> for use with the block list editor property value editor.
/// </summary>
/// <returns>A new instance of <see cref="BlockListEditorDataConverter"/>.</returns>
protected virtual BlockEditorDataConverter CreateBlockEditorDataConverter() => new BlockListEditorDataConverter();
protected override IDataValueEditor CreateValueEditor() =>
DataValueEditorFactory.Create<BlockListEditorPropertyValueEditor>(Attribute!, CreateBlockEditorDataConverter());
internal class BlockListEditorPropertyValueEditor : BlockEditorPropertyValueEditor
{
public BlockListEditorPropertyValueEditor(
DataEditorAttribute attribute,
BlockEditorDataConverter blockEditorDataConverter,
PropertyEditorCollection propertyEditors,
DataValueReferenceFactoryCollection dataValueReferenceFactories,
IDataTypeConfigurationCache dataTypeConfigurationCache,
IBlockEditorElementTypeCache elementTypeCache,
ILocalizedTextService textService,
ILogger<BlockEditorPropertyValueEditor> logger,
IShortStringHelper shortStringHelper,
IJsonSerializer jsonSerializer,
IIOHelper ioHelper,
IPropertyValidationService propertyValidationService) :
base(attribute, propertyEditors, dataValueReferenceFactories, dataTypeConfigurationCache, textService, logger, shortStringHelper, jsonSerializer, ioHelper)
{
BlockEditorValues = new BlockEditorValues(blockEditorDataConverter, elementTypeCache, logger);
Validators.Add(new BlockEditorValidator(propertyValidationService, BlockEditorValues, elementTypeCache));
Validators.Add(new MinMaxValidator(BlockEditorValues, textService));
}
private class MinMaxValidator : BlockEditorMinMaxValidatorBase
{
private readonly BlockEditorValues _blockEditorValues;
public MinMaxValidator(BlockEditorValues blockEditorValues, ILocalizedTextService textService)
: base(textService) =>
_blockEditorValues = blockEditorValues;
public override IEnumerable<ValidationResult> Validate(object? value, string? valueType, object? dataTypeConfiguration)
{
var blockConfig = (BlockListConfiguration?)dataTypeConfiguration;
BlockListConfiguration.NumberRange? validationLimit = blockConfig?.ValidationLimit;
if (validationLimit == null)
{
return Array.Empty<ValidationResult>();
}
BlockEditorData? blockEditorData = _blockEditorValues.DeserializeAndClean(value);
return ValidateNumberOfBlocks(blockEditorData, validationLimit.Min, validationLimit.Max);
}
}
}
#endregion
}