Skip to content

Commit 5660c6c

Browse files
kjacAndyButland
andauthored
Forward merge #19720 to V16 (#19735)
* Add support for programmatic creation of property types providing the data type key (#19720) * Add support for programmatic creation of property types providing the data type key. * Add integration tests --------- Co-authored-by: kjac <[email protected]> * Don't use Lazy --------- Co-authored-by: Andy Butland <[email protected]>
1 parent 698d566 commit 5660c6c

File tree

11 files changed

+136
-38
lines changed

11 files changed

+136
-38
lines changed

src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepository.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Umbraco.Cms.Core.Models;
66
using Umbraco.Cms.Core.Persistence.Querying;
77
using Umbraco.Cms.Core.Persistence.Repositories;
8+
using Umbraco.Cms.Core.Services;
89
using Umbraco.Cms.Core.Strings;
910
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
1011
using Umbraco.Cms.Infrastructure.Persistence.Querying;
@@ -25,8 +26,9 @@ public ContentTypeRepository(
2526
ILogger<ContentTypeRepository> logger,
2627
IContentTypeCommonRepository commonRepository,
2728
ILanguageRepository languageRepository,
28-
IShortStringHelper shortStringHelper)
29-
: base(scopeAccessor, cache, logger, commonRepository, languageRepository, shortStringHelper)
29+
IShortStringHelper shortStringHelper,
30+
IIdKeyMap idKeyMap)
31+
: base(scopeAccessor, cache, logger, commonRepository, languageRepository, shortStringHelper, idKeyMap)
3032
{
3133
}
3234

src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs

Lines changed: 55 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -29,15 +29,22 @@ internal abstract class ContentTypeRepositoryBase<TEntity> : EntityRepositoryBas
2929
where TEntity : class, IContentTypeComposition
3030
{
3131
private readonly IShortStringHelper _shortStringHelper;
32-
33-
protected ContentTypeRepositoryBase(IScopeAccessor scopeAccessor, AppCaches cache,
34-
ILogger<ContentTypeRepositoryBase<TEntity>> logger, IContentTypeCommonRepository commonRepository,
35-
ILanguageRepository languageRepository, IShortStringHelper shortStringHelper)
32+
private readonly IIdKeyMap _idKeyMap;
33+
34+
protected ContentTypeRepositoryBase(
35+
IScopeAccessor scopeAccessor,
36+
AppCaches cache,
37+
ILogger<ContentTypeRepositoryBase<TEntity>> logger,
38+
IContentTypeCommonRepository commonRepository,
39+
ILanguageRepository languageRepository,
40+
IShortStringHelper shortStringHelper,
41+
IIdKeyMap idKeyMap)
3642
: base(scopeAccessor, cache, logger)
3743
{
3844
_shortStringHelper = shortStringHelper;
3945
CommonRepository = commonRepository;
4046
LanguageRepository = languageRepository;
47+
_idKeyMap = idKeyMap;
4148
}
4249

4350
protected IContentTypeCommonRepository CommonRepository { get; }
@@ -291,7 +298,7 @@ protected void PersistNewBaseContentType(IContentTypeComposition entity)
291298
// If the Id of the DataType is not set, we resolve it from the db by its PropertyEditorAlias
292299
if (propertyType.DataTypeId == 0 || propertyType.DataTypeId == default)
293300
{
294-
AssignDataTypeFromPropertyEditor(propertyType);
301+
AssignDataTypeIdFromProvidedKeyOrPropertyEditor(propertyType);
295302
}
296303

297304
PropertyTypeDto propertyTypeDto =
@@ -592,7 +599,7 @@ protected void PersistUpdatedBaseContentType(IContentTypeComposition entity)
592599
// if the Id of the DataType is not set, we resolve it from the db by its PropertyEditorAlias
593600
if (propertyType.DataTypeId == 0 || propertyType.DataTypeId == default)
594601
{
595-
AssignDataTypeFromPropertyEditor(propertyType);
602+
AssignDataTypeIdFromProvidedKeyOrPropertyEditor(propertyType);
596603
}
597604

598605
// validate the alias
@@ -1434,37 +1441,59 @@ protected void ValidateAlias(TEntity entity)
14341441
protected abstract TEntity? PerformGet(Guid id);
14351442

14361443
/// <summary>
1437-
/// Try to set the data type id based on its ControlId
1444+
/// Try to set the data type Id based on the provided key or property editor alias.
14381445
/// </summary>
14391446
/// <param name="propertyType"></param>
1440-
private void AssignDataTypeFromPropertyEditor(IPropertyType propertyType)
1447+
private void AssignDataTypeIdFromProvidedKeyOrPropertyEditor(IPropertyType propertyType)
14411448
{
1442-
// we cannot try to assign a data type of it's empty
1443-
if (propertyType.PropertyEditorAlias.IsNullOrWhiteSpace() == false)
1449+
// If a key is provided, use that.
1450+
if (propertyType.DataTypeKey != Guid.Empty)
14441451
{
1445-
Sql<ISqlContext> sql = Sql()
1446-
.Select<DataTypeDto>(dt => dt.Select(x => x.NodeDto))
1447-
.From<DataTypeDto>()
1448-
.InnerJoin<NodeDto>().On<DataTypeDto, NodeDto>((dt, n) => dt.NodeId == n.NodeId)
1449-
.Where(
1450-
"propertyEditorAlias = @propertyEditorAlias",
1451-
new { propertyEditorAlias = propertyType.PropertyEditorAlias })
1452-
.OrderBy<DataTypeDto>(typeDto => typeDto.NodeId);
1453-
DataTypeDto? datatype = Database.FirstOrDefault<DataTypeDto>(sql);
1454-
1455-
// we cannot assign a data type if one was not found
1456-
if (datatype != null)
1452+
Attempt<int> dataTypeIdAttempt = _idKeyMap.GetIdForKey(propertyType.DataTypeKey, UmbracoObjectTypes.DataType);
1453+
if (dataTypeIdAttempt.Success)
14571454
{
1458-
propertyType.DataTypeId = datatype.NodeId;
1459-
propertyType.DataTypeKey = datatype.NodeDto.UniqueId;
1455+
propertyType.DataTypeId = dataTypeIdAttempt.Result;
1456+
return;
14601457
}
14611458
else
14621459
{
14631460
Logger.LogWarning(
1464-
"Could not assign a data type for the property type {PropertyTypeAlias} since no data type was found with a property editor {PropertyEditorAlias}",
1465-
propertyType.Alias, propertyType.PropertyEditorAlias);
1461+
"Could not assign a data type for the property type {PropertyTypeAlias} since no integer Id was found matching the key {DataTypeKey}. Falling back to look up via the property editor alias.",
1462+
propertyType.Alias,
1463+
propertyType.DataTypeKey);
14661464
}
14671465
}
1466+
1467+
// Otherwise if a property editor alias is provided, try to find a data type that uses that alias.
1468+
if (propertyType.PropertyEditorAlias.IsNullOrWhiteSpace())
1469+
{
1470+
// We cannot try to assign a data type if it's empty.
1471+
return;
1472+
}
1473+
1474+
Sql<ISqlContext> sql = Sql()
1475+
.Select<DataTypeDto>(dt => dt.Select(x => x.NodeDto))
1476+
.From<DataTypeDto>()
1477+
.InnerJoin<NodeDto>().On<DataTypeDto, NodeDto>((dt, n) => dt.NodeId == n.NodeId)
1478+
.Where(
1479+
"propertyEditorAlias = @propertyEditorAlias",
1480+
new { propertyEditorAlias = propertyType.PropertyEditorAlias })
1481+
.OrderBy<DataTypeDto>(typeDto => typeDto.NodeId);
1482+
DataTypeDto? datatype = Database.FirstOrDefault<DataTypeDto>(sql);
1483+
1484+
// we cannot assign a data type if one was not found
1485+
if (datatype != null)
1486+
{
1487+
propertyType.DataTypeId = datatype.NodeId;
1488+
propertyType.DataTypeKey = datatype.NodeDto.UniqueId;
1489+
}
1490+
else
1491+
{
1492+
Logger.LogWarning(
1493+
"Could not assign a data type for the property type {PropertyTypeAlias} since no data type was found with a property editor {PropertyEditorAlias}",
1494+
propertyType.Alias,
1495+
propertyType.PropertyEditorAlias);
1496+
}
14681497
}
14691498

14701499
protected abstract TEntity? PerformGet(string alias);

src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MediaTypeRepository.cs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Umbraco.Cms.Core.Models;
66
using Umbraco.Cms.Core.Persistence.Querying;
77
using Umbraco.Cms.Core.Persistence.Repositories;
8+
using Umbraco.Cms.Core.Services;
89
using Umbraco.Cms.Core.Strings;
910
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
1011
using Umbraco.Cms.Infrastructure.Persistence.Querying;
@@ -24,8 +25,9 @@ public MediaTypeRepository(
2425
ILogger<MediaTypeRepository> logger,
2526
IContentTypeCommonRepository commonRepository,
2627
ILanguageRepository languageRepository,
27-
IShortStringHelper shortStringHelper)
28-
: base(scopeAccessor, cache, logger, commonRepository, languageRepository, shortStringHelper)
28+
IShortStringHelper shortStringHelper,
29+
IIdKeyMap idKeyMap)
30+
: base(scopeAccessor, cache, logger, commonRepository, languageRepository, shortStringHelper, idKeyMap)
2931
{
3032
}
3133

src/Umbraco.Infrastructure/Persistence/Repositories/Implement/MemberTypeRepository.cs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
using Umbraco.Cms.Core.Models;
66
using Umbraco.Cms.Core.Persistence.Querying;
77
using Umbraco.Cms.Core.Persistence.Repositories;
8+
using Umbraco.Cms.Core.Services;
89
using Umbraco.Cms.Core.Strings;
910
using Umbraco.Cms.Infrastructure.Persistence.Dtos;
1011
using Umbraco.Cms.Infrastructure.Persistence.Factories;
@@ -27,9 +28,10 @@ public MemberTypeRepository(
2728
ILogger<MemberTypeRepository> logger,
2829
IContentTypeCommonRepository commonRepository,
2930
ILanguageRepository languageRepository,
30-
IShortStringHelper shortStringHelper)
31-
: base(scopeAccessor, cache, logger, commonRepository, languageRepository, shortStringHelper) =>
32-
_shortStringHelper = shortStringHelper;
31+
IShortStringHelper shortStringHelper,
32+
IIdKeyMap idKeyMap)
33+
: base(scopeAccessor, cache, logger, commonRepository, languageRepository, shortStringHelper, idKeyMap)
34+
=> _shortStringHelper = shortStringHelper;
3335

3436
protected override bool SupportsPublishing => MemberType.SupportsPublishingConst;
3537

tests/Umbraco.Tests.Integration/Testing/UmbracoIntegrationTest.cs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ public abstract class UmbracoIntegrationTest : UmbracoIntegrationTestBase
6060

6161
protected IShortStringHelper ShortStringHelper => Services.GetRequiredService<IShortStringHelper>();
6262

63+
protected IIdKeyMap IdKeyMap => Services.GetRequiredService<IIdKeyMap>();
64+
6365
protected GlobalSettings GlobalSettings => Services.GetRequiredService<IOptions<GlobalSettings>>().Value;
6466

6567
protected IMapperCollection Mappers => Services.GetRequiredService<IMapperCollection>();

tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/DocumentRepositoryTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ private DocumentRepository CreateRepository(IScopeAccessor scopeAccessor, out Co
123123
new ContentTypeCommonRepository(scopeAccessor, templateRepository, appCaches, ShortStringHelper);
124124
var languageRepository =
125125
new LanguageRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger<LanguageRepository>());
126-
contentTypeRepository = new ContentTypeRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger<ContentTypeRepository>(), commonRepository, languageRepository, ShortStringHelper);
126+
contentTypeRepository = new ContentTypeRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger<ContentTypeRepository>(), commonRepository, languageRepository, ShortStringHelper, IdKeyMap);
127127
var relationTypeRepository = new RelationTypeRepository(scopeAccessor, AppCaches.Disabled, LoggerFactory.CreateLogger<RelationTypeRepository>());
128128
var entityRepository = new EntityRepository(scopeAccessor, AppCaches.Disabled);
129129
var relationRepository = new RelationRepository(scopeAccessor, LoggerFactory.CreateLogger<RelationRepository>(), relationTypeRepository, entityRepository);

tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MediaRepositoryTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ private MediaRepository CreateRepository(IScopeProvider provider, out MediaTypeR
5656
new ContentTypeCommonRepository(scopeAccessor, TemplateRepository, appCaches, ShortStringHelper);
5757
var languageRepository =
5858
new LanguageRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger<LanguageRepository>());
59-
mediaTypeRepository = new MediaTypeRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger<MediaTypeRepository>(), commonRepository, languageRepository, ShortStringHelper);
59+
mediaTypeRepository = new MediaTypeRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger<MediaTypeRepository>(), commonRepository, languageRepository, ShortStringHelper, IdKeyMap);
6060
var tagRepository = new TagRepository(scopeAccessor, appCaches, LoggerFactory.CreateLogger<TagRepository>());
6161
var relationTypeRepository = new RelationTypeRepository(scopeAccessor, AppCaches.Disabled, LoggerFactory.CreateLogger<RelationTypeRepository>());
6262
var entityRepository = new EntityRepository(scopeAccessor, AppCaches.Disabled);

tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MediaTypeRepositoryTest.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
using Umbraco.Cms.Core.Models;
1010
using Umbraco.Cms.Core.Persistence;
1111
using Umbraco.Cms.Core.Persistence.Repositories;
12+
using Umbraco.Cms.Core.Services;
1213
using Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement;
1314
using Umbraco.Cms.Infrastructure.Scoping;
1415
using Umbraco.Cms.Tests.Common.Builders;
@@ -411,7 +412,7 @@ public void Can_Verify_PropertyTypes_On_File_MediaType()
411412
}
412413

413414
private MediaTypeRepository CreateRepository(IScopeProvider provider) =>
414-
new((IScopeAccessor)provider, AppCaches.Disabled, LoggerFactory.CreateLogger<MediaTypeRepository>(), CommonRepository, LanguageRepository, ShortStringHelper);
415+
new((IScopeAccessor)provider, AppCaches.Disabled, LoggerFactory.CreateLogger<MediaTypeRepository>(), CommonRepository, LanguageRepository, ShortStringHelper, IdKeyMap);
415416

416417
private EntityContainerRepository CreateContainerRepository(IScopeProvider provider) =>
417418
new((IScopeAccessor)provider, AppCaches.Disabled, LoggerFactory.CreateLogger<EntityContainerRepository>(), Constants.ObjectTypes.MediaTypeContainer);

tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/MemberTypeRepositoryTest.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using Umbraco.Cms.Core.Models;
1111
using Umbraco.Cms.Core.Persistence;
1212
using Umbraco.Cms.Core.Persistence.Repositories;
13+
using Umbraco.Cms.Core.Services;
1314
using Umbraco.Cms.Infrastructure.Persistence.Repositories.Implement;
1415
using Umbraco.Cms.Infrastructure.Scoping;
1516
using Umbraco.Cms.Tests.Common.Builders;
@@ -26,7 +27,7 @@ private MemberTypeRepository CreateRepository(IScopeProvider provider)
2627
{
2728
var commonRepository = GetRequiredService<IContentTypeCommonRepository>();
2829
var languageRepository = GetRequiredService<ILanguageRepository>();
29-
return new MemberTypeRepository((IScopeAccessor)provider, AppCaches.Disabled, Mock.Of<ILogger<MemberTypeRepository>>(), commonRepository, languageRepository, ShortStringHelper);
30+
return new MemberTypeRepository((IScopeAccessor)provider, AppCaches.Disabled, Mock.Of<ILogger<MemberTypeRepository>>(), commonRepository, languageRepository, ShortStringHelper, IdKeyMap);
3031
}
3132

3233
[Test]

tests/Umbraco.Tests.Integration/Umbraco.Infrastructure/Persistence/Repositories/TemplateRepositoryTest.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ public void Can_Perform_Delete_When_Assigned_To_Doc()
266266
var commonRepository =
267267
new ContentTypeCommonRepository(scopeAccessor, templateRepository, AppCaches, ShortStringHelper);
268268
var languageRepository = new LanguageRepository(scopeAccessor, AppCaches.Disabled, LoggerFactory.CreateLogger<LanguageRepository>());
269-
var contentTypeRepository = new ContentTypeRepository(scopeAccessor, AppCaches.Disabled, LoggerFactory.CreateLogger<ContentTypeRepository>(), commonRepository, languageRepository, ShortStringHelper);
269+
var contentTypeRepository = new ContentTypeRepository(scopeAccessor, AppCaches.Disabled, LoggerFactory.CreateLogger<ContentTypeRepository>(), commonRepository, languageRepository, ShortStringHelper, IdKeyMap);
270270
var relationTypeRepository = new RelationTypeRepository(scopeAccessor, AppCaches.Disabled, LoggerFactory.CreateLogger<RelationTypeRepository>());
271271
var entityRepository = new EntityRepository(scopeAccessor, AppCaches.Disabled);
272272
var relationRepository = new RelationRepository(scopeAccessor, LoggerFactory.CreateLogger<RelationRepository>(), relationTypeRepository, entityRepository);

0 commit comments

Comments
 (0)