diff --git a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Editors/DefaultContentDefinitionDisplayManager.cs b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Editors/DefaultContentDefinitionDisplayManager.cs index 353b2f3fa16..bad5c34cbae 100644 --- a/src/OrchardCore.Modules/OrchardCore.ContentTypes/Editors/DefaultContentDefinitionDisplayManager.cs +++ b/src/OrchardCore.Modules/OrchardCore.ContentTypes/Editors/DefaultContentDefinitionDisplayManager.cs @@ -82,7 +82,7 @@ public async Task UpdateTypeEditorAsync(ContentTypeDefinition contentTy var layout = await _layoutAccessor.GetLayoutAsync(); - _contentDefinitionManager.AlterTypeDefinition(contentTypeDefinition.Name, typeBuilder => + await _contentDefinitionManager.AlterTypeDefinitionAsync(contentTypeDefinition.Name, async typeBuilder => { var typeContext = new UpdateTypeEditorContext( typeBuilder, @@ -94,9 +94,9 @@ public async Task UpdateTypeEditorAsync(ContentTypeDefinition contentTy updater ); - BindPlacementAsync(typeContext).GetAwaiter().GetResult(); + await BindPlacementAsync(typeContext); - _handlers.InvokeAsync((handler, contentTypeDefinition, typeContext) => handler.UpdateTypeEditorAsync(contentTypeDefinition, typeContext), contentTypeDefinition, typeContext, _logger).GetAwaiter().GetResult(); + await _handlers.InvokeAsync((handler, contentTypeDefinition, typeContext) => handler.UpdateTypeEditorAsync(contentTypeDefinition, typeContext), contentTypeDefinition, typeContext, _logger); }); return contentTypeDefinitionShape; @@ -140,7 +140,7 @@ public async Task UpdatePartEditorAsync(ContentPartDefinition contentPa UpdatePartEditorContext partContext = null; var layout = await _layoutAccessor.GetLayoutAsync(); - _contentDefinitionManager.AlterPartDefinition(contentPartDefinition.Name, partBuilder => + await _contentDefinitionManager.AlterPartDefinitionAsync(contentPartDefinition.Name, async partBuilder => { partContext = new UpdatePartEditorContext( partBuilder, @@ -152,9 +152,9 @@ public async Task UpdatePartEditorAsync(ContentPartDefinition contentPa updater ); - BindPlacementAsync(partContext).GetAwaiter().GetResult(); + await BindPlacementAsync(partContext); - _handlers.InvokeAsync((handler, contentPartDefinition, partContext) => handler.UpdatePartEditorAsync(contentPartDefinition, partContext), contentPartDefinition, partContext, _logger).GetAwaiter().GetResult(); + await _handlers.InvokeAsync((handler, contentPartDefinition, partContext) => handler.UpdatePartEditorAsync(contentPartDefinition, partContext), contentPartDefinition, partContext, _logger); }); return contentPartDefinitionShape; @@ -197,9 +197,9 @@ public async Task UpdateTypePartEditorAsync(ContentTypePartDefinition c dynamic typePartDefinitionShape = await CreateContentShapeAsync("ContentTypePartDefinition_Edit"); var layout = await _layoutAccessor.GetLayoutAsync(); - _contentDefinitionManager.AlterTypeDefinition(contentTypePartDefinition.ContentTypeDefinition.Name, typeBuilder => + await _contentDefinitionManager.AlterTypeDefinitionAsync(contentTypePartDefinition.ContentTypeDefinition.Name, typeBuilder => { - typeBuilder.WithPart(contentTypePartDefinition.Name, async typePartBuilder => + return typeBuilder.WithPartAsync(contentTypePartDefinition.Name, async typePartBuilder => { typePartDefinitionShape.ContentPart = contentTypePartDefinition; @@ -261,9 +261,9 @@ public async Task UpdatePartFieldEditorAsync(ContentPartFieldDefinition var layout = await _layoutAccessor.GetLayoutAsync(); - _contentDefinitionManager.AlterPartDefinition(contentPartDefinition.Name, partBuilder => + await _contentDefinitionManager.AlterPartDefinitionAsync(contentPartDefinition.Name, partBuilder => { - partBuilder.WithField(contentPartFieldDefinition.Name, async partFieldBuilder => + return partBuilder.WithFieldAsync(contentPartFieldDefinition.Name, async partFieldBuilder => { partFieldDefinitionShape.ContentField = contentPartFieldDefinition; diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/IContentDefinitionManager.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/IContentDefinitionManager.cs index add8ce2f6b2..cfc56ce0f82 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/IContentDefinitionManager.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/IContentDefinitionManager.cs @@ -52,6 +52,15 @@ public static void AlterTypeDefinition(this IContentDefinitionManager manager, s alteration(builder); manager.StoreTypeDefinition(builder.Build()); } + + public static async Task AlterTypeDefinitionAsync(this IContentDefinitionManager manager, string name, Func alterationAsync) + { + var typeDefinition = manager.LoadTypeDefinition(name) ?? new ContentTypeDefinition(name, name.CamelFriendly()); + var builder = new ContentTypeDefinitionBuilder(typeDefinition); + await alterationAsync(builder); + manager.StoreTypeDefinition(builder.Build()); + } + public static void AlterPartDefinition(this IContentDefinitionManager manager, string name, Action alteration) { var partDefinition = manager.LoadPartDefinition(name) ?? new ContentPartDefinition(name); @@ -60,6 +69,14 @@ public static void AlterPartDefinition(this IContentDefinitionManager manager, s manager.StorePartDefinition(builder.Build()); } + public static async Task AlterPartDefinitionAsync(this IContentDefinitionManager manager, string name, Func alterationAsync) + { + var partDefinition = manager.LoadPartDefinition(name) ?? new ContentPartDefinition(name); + var builder = new ContentPartDefinitionBuilder(partDefinition); + await alterationAsync(builder); + manager.StorePartDefinition(builder.Build()); + } + /// /// Migrate existing ContentPart settings to WithSettings /// This method will be removed in a future release. diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentPartDefinitionBuilder.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentPartDefinitionBuilder.cs index f824c9e6323..2a411b75658 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentPartDefinitionBuilder.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentPartDefinitionBuilder.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Newtonsoft.Json.Linq; using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentManagement.Utilities; @@ -137,6 +138,32 @@ public ContentPartDefinitionBuilder WithField(string fieldName, Action WithFieldAsync(string fieldName, Func configurationAsync) + { + var existingField = _fields.FirstOrDefault(x => x.Name == fieldName); + + if (existingField != null) + { + var toRemove = _fields.Where(x => x.Name == fieldName).ToArray(); + foreach (var remove in toRemove) + { + _fields.Remove(remove); + } + } + else + { + existingField = new ContentPartFieldDefinition(null, fieldName, new JObject()); + } + + var configurer = new FieldConfigurerImpl(existingField, _part); + + await configurationAsync(configurer); + + _fields.Add(configurer.Build()); + + return this; + } + private class FieldConfigurerImpl : ContentPartFieldDefinitionBuilder { private ContentFieldDefinition _fieldDefinition; diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentTypeDefinitionBuilder.cs b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentTypeDefinitionBuilder.cs index 6bea8c8f8db..f8afeb9d7ff 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentTypeDefinitionBuilder.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Abstractions/Metadata/Builders/ContentTypeDefinitionBuilder.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using System.Threading.Tasks; using Newtonsoft.Json.Linq; using OrchardCore.ContentManagement.Metadata.Models; using OrchardCore.ContentManagement.Utilities; @@ -155,6 +156,39 @@ public ContentTypeDefinitionBuilder WithPart(string name, ContentPartDefinition return this; } + public Task WithPartAsync(string name, string partName, Func configurationAsync) + { + return WithPartAsync(name, new ContentPartDefinition(partName), configurationAsync); + } + + public Task WithPartAsync(string partName, Func configurationAsync) + { + return WithPartAsync(partName, new ContentPartDefinition(partName), configurationAsync); + } + + public async Task WithPartAsync(string name, ContentPartDefinition partDefinition, Func configurationAsync) + { + var existingPart = _parts.FirstOrDefault(x => x.Name == name); + + if (existingPart != null) + { + _parts.Remove(existingPart); + } + else + { + existingPart = new ContentTypePartDefinition(name, partDefinition, new JObject()); + existingPart.ContentTypeDefinition = Current; + } + + var configurer = new PartConfigurerImpl(existingPart); + + await configurationAsync(configurer); + + _parts.Add(configurer.Build()); + + return this; + } + private class PartConfigurerImpl : ContentTypePartDefinitionBuilder { private readonly ContentPartDefinition _partDefinition;