diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/ContentOptionsDisplayDriver.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/ContentOptionsDisplayDriver.cs index 4316c44f399..53eed647f85 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/ContentOptionsDisplayDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/ContentOptionsDisplayDriver.cs @@ -8,7 +8,7 @@ namespace OrchardCore.Contents.Drivers { public class ContentOptionsDisplayDriver : DisplayDriver { - // Maintain the Options prefix for compatability with binding. + // Maintain the Options prefix for compatibility with binding. protected override void BuildPrefix(ContentOptionsViewModel model, string htmlFieldPrefix) { Prefix = "Options"; @@ -36,7 +36,6 @@ public override IDisplayResult Edit(ContentOptionsViewModel model) Initialize("ContentsAdminListSummary", m => BuildContentOptionsViewModel(m, model)).Location("Summary:10"), Initialize("ContentsAdminListFilters", m => BuildContentOptionsViewModel(m, model)).Location("Actions:10.1"), Initialize("ContentsAdminList_Fields_BulkActions", m => BuildContentOptionsViewModel(m, model)).Location("Actions:10.1") - ); } @@ -45,7 +44,7 @@ public override Task UpdateAsync(ContentOptionsViewModel model, // Map the incoming values from a form post to the filter result. model.FilterResult.MapFrom(model); - return Task.FromResult(Edit(model)); + return Task.FromResult(Edit(model)); } private static void BuildContentOptionsViewModel(ContentOptionsViewModel m, ContentOptionsViewModel model) diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/ContentsDriver.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/ContentsDriver.cs index 36bdb9d5d4e..385d611ccbb 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/ContentsDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/ContentsDriver.cs @@ -34,15 +34,21 @@ public override async Task DisplayAsync(ContentItem contentItem, // We add custom alternates. This could be done generically to all shapes coming from ContentDisplayDriver but right now it's // only necessary on this shape. Otherwise c.f. ContentPartDisplayDriver - var context = _httpContextAccessor.HttpContext; - var results = new List(); + var contentItemViewModel = new ContentItemViewModel(contentItem); + + var results = new List() + { + Shape("ContentsTags_SummaryAdmin", contentItemViewModel).Location("SummaryAdmin", "Tags:10"), + Shape("ContentsMeta_SummaryAdmin", contentItemViewModel).Location("SummaryAdmin", "Meta:20"), + }; + var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); - var contentsMetadataShape = Shape("ContentsMetadata", - new ContentItemViewModel(contentItem)) - .Location("Detail", "Content:before"); if (contentTypeDefinition != null) { + var contentsMetadataShape = Shape("ContentsMetadata", contentItemViewModel) + .Location("Detail", "Content:before"); + contentsMetadataShape.Displaying(ctx => { var hasStereotype = contentTypeDefinition.TryGetStereotype(out var stereotype); @@ -65,60 +71,47 @@ public override async Task DisplayAsync(ContentItem contentItem, } }); + var user = _httpContextAccessor.HttpContext.User; + results.Add(contentsMetadataShape); - results.Add(Shape("ContentsButtonEdit_SummaryAdmin", new ContentItemViewModel(contentItem)).Location("SummaryAdmin", "Actions:10")); - results.Add(Shape("ContentsButtonActions_SummaryAdmin", new ContentItemViewModel(contentItem)).Location("SummaryAdmin", "ActionsMenu:10") + results.Add(Shape("ContentsButtonEdit_SummaryAdmin", contentItemViewModel).Location("SummaryAdmin", "Actions:10")); + results.Add(Shape("ContentsButtonActions_SummaryAdmin", contentItemViewModel).Location("SummaryAdmin", "ActionsMenu:10") .RenderWhen(async () => { - var hasPublishPermission = await _authorizationService.AuthorizeAsync(context.User, CommonPermissions.PublishContent, contentItem); - var hasDeletePermission = await _authorizationService.AuthorizeAsync(context.User, CommonPermissions.DeleteContent, contentItem); - var hasPreviewPermission = await _authorizationService.AuthorizeAsync(context.User, CommonPermissions.PreviewContent, contentItem); - var hasClonePermission = await _authorizationService.AuthorizeAsync(context.User, CommonPermissions.CloneContent, contentItem); + var hasPublishPermission = await _authorizationService.AuthorizeAsync(user, CommonPermissions.PublishContent, contentItem); + var hasDeletePermission = await _authorizationService.AuthorizeAsync(user, CommonPermissions.DeleteContent, contentItem); + var hasPreviewPermission = await _authorizationService.AuthorizeAsync(user, CommonPermissions.PreviewContent, contentItem); + var hasClonePermission = await _authorizationService.AuthorizeAsync(user, CommonPermissions.CloneContent, contentItem); - if (hasPublishPermission || hasDeletePermission || hasPreviewPermission || hasClonePermission) - { - return true; - } - - return false; + return hasPublishPermission || hasDeletePermission || hasPreviewPermission || hasClonePermission; }) ); } - results.Add(Shape("ContentsTags_SummaryAdmin", new ContentItemViewModel(contentItem)).Location("SummaryAdmin", "Tags:10")); - results.Add(Shape("ContentsMeta_SummaryAdmin", new ContentItemViewModel(contentItem)).Location("SummaryAdmin", "Meta:20")); - - return Combine(results.ToArray()); + return Combine(results); } public override async Task EditAsync(ContentItem contentItem, IUpdateModel updater) { - var context = _httpContextAccessor.HttpContext; var contentTypeDefinition = await _contentDefinitionManager.GetTypeDefinitionAsync(contentItem.ContentType); - var results = new List(); if (contentTypeDefinition == null) { return null; } - results.Add(Dynamic("Content_PublishButton").Location("Actions:10") - .RenderWhen(() => _authorizationService.AuthorizeAsync(context.User, CommonPermissions.PublishContent, contentItem))); + var context = _httpContextAccessor.HttpContext; - results.Add(Dynamic("Content_SaveDraftButton").Location("Actions:20") - .RenderWhen(async () => - { - if (contentTypeDefinition.IsDraftable() && - await _authorizationService.AuthorizeAsync(context.User, CommonPermissions.EditContent, contentItem)) + return Combine( + Dynamic("Content_PublishButton").Location("Actions:10") + .RenderWhen(() => _authorizationService.AuthorizeAsync(context.User, CommonPermissions.PublishContent, contentItem)), + Dynamic("Content_SaveDraftButton").Location("Actions:20") + .RenderWhen(async () => { - return true; - } - - return false; - }) - ); - - return Combine(results.ToArray()); + return contentTypeDefinition.IsDraftable() + && await _authorizationService.AuthorizeAsync(context.User, CommonPermissions.EditContent, contentItem); + }) + ); } } } diff --git a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/DateEditorDriver.cs b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/DateEditorDriver.cs index b4c761ee04c..f1fcb4c2b68 100644 --- a/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/DateEditorDriver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Contents/Drivers/DateEditorDriver.cs @@ -1,4 +1,3 @@ -using System; using System.Threading.Tasks; using OrchardCore.ContentManagement.Display.ContentDisplay; using OrchardCore.ContentManagement.Display.Models; @@ -28,7 +27,7 @@ public override IDisplayResult Edit(CommonPart part, BuildPartEditorContext cont return Initialize("CommonPart_Edit__Date", async model => { model.LocalDateTime = part.ContentItem.CreatedUtc.HasValue - ? (DateTime?)(await _localClock.ConvertToLocalAsync(part.ContentItem.CreatedUtc.Value)).DateTime + ? (await _localClock.ConvertToLocalAsync(part.ContentItem.CreatedUtc.Value)).DateTime : null; }); } diff --git a/src/OrchardCore.Modules/OrchardCore.Templates/Services/AdminTemplatesShapeBindingResolver.cs b/src/OrchardCore.Modules/OrchardCore.Templates/Services/AdminTemplatesShapeBindingResolver.cs index b04c6690c07..067fdc200b2 100644 --- a/src/OrchardCore.Modules/OrchardCore.Templates/Services/AdminTemplatesShapeBindingResolver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Templates/Services/AdminTemplatesShapeBindingResolver.cs @@ -41,12 +41,9 @@ public async Task GetShapeBindingAsync(string shapeType) var localTemplates = _previewTemplatesProvider.GetTemplates(); - if (localTemplates != null) + if (localTemplates != null && localTemplates.Templates.TryGetValue(shapeType, out var localTemplate)) { - if (localTemplates.Templates.TryGetValue(shapeType, out var localTemplate)) - { - return BuildShapeBinding(shapeType, localTemplate); - } + return BuildShapeBinding(shapeType, localTemplate); } _templatesDocument ??= await _templatesManager.GetTemplatesDocumentAsync(); @@ -55,10 +52,8 @@ public async Task GetShapeBindingAsync(string shapeType) { return BuildShapeBinding(shapeType, template); } - else - { - return null; - } + + return null; } private ShapeBinding BuildShapeBinding(string shapeType, Template template) diff --git a/src/OrchardCore.Modules/OrchardCore.Templates/Services/TemplatesShapeBindingResolver.cs b/src/OrchardCore.Modules/OrchardCore.Templates/Services/TemplatesShapeBindingResolver.cs index d4788f2009f..58be7015a5f 100644 --- a/src/OrchardCore.Modules/OrchardCore.Templates/Services/TemplatesShapeBindingResolver.cs +++ b/src/OrchardCore.Modules/OrchardCore.Templates/Services/TemplatesShapeBindingResolver.cs @@ -41,12 +41,9 @@ public async Task GetShapeBindingAsync(string shapeType) var localTemplates = _previewTemplatesProvider.GetTemplates(); - if (localTemplates != null) + if (localTemplates != null && localTemplates.Templates.TryGetValue(shapeType, out var localTemplate)) { - if (localTemplates.Templates.TryGetValue(shapeType, out var localTemplate)) - { - return BuildShapeBinding(shapeType, localTemplate); - } + return BuildShapeBinding(shapeType, localTemplate); } _templatesDocument ??= await _templatesManager.GetTemplatesDocumentAsync(); @@ -55,10 +52,8 @@ public async Task GetShapeBindingAsync(string shapeType) { return BuildShapeBinding(shapeType, template); } - else - { - return null; - } + + return null; } private ShapeBinding BuildShapeBinding(string shapeType, Template template) diff --git a/src/OrchardCore/OrchardCore.Admin.Abstractions/AdminAttribute.cs b/src/OrchardCore/OrchardCore.Admin.Abstractions/AdminAttribute.cs index 5dfe1b170db..4cdee6c6332 100644 --- a/src/OrchardCore/OrchardCore.Admin.Abstractions/AdminAttribute.cs +++ b/src/OrchardCore/OrchardCore.Admin.Abstractions/AdminAttribute.cs @@ -56,6 +56,7 @@ public static void Apply(HttpContext context) context.Items[typeof(AdminAttribute)] = null; } - public static bool IsApplied(HttpContext context) => context.Items.TryGetValue(typeof(AdminAttribute), out _); + public static bool IsApplied(HttpContext context) + => context.Items.ContainsKey(typeof(AdminAttribute)); } } diff --git a/src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplay/ContentFieldDisplayDriver.cs b/src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplay/ContentFieldDisplayDriver.cs index 396d2a8de69..67c8e1b6df1 100644 --- a/src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplay/ContentFieldDisplayDriver.cs +++ b/src/OrchardCore/OrchardCore.ContentManagement.Display/ContentDisplay/ContentFieldDisplayDriver.cs @@ -63,7 +63,7 @@ public override ShapeResult Factory(string shapeType, Func { - var displayTypes = new[] { "", "_" + ctx.Shape.Metadata.DisplayType }; + var displayTypes = new[] { string.Empty, "_" + ctx.Shape.Metadata.DisplayType }; // [ShapeType]_[DisplayType], e.g. TextField.Summary ctx.Shape.Metadata.Alternates.Add($"{shapeType}_{ctx.Shape.Metadata.DisplayType}"); @@ -100,7 +100,7 @@ public override ShapeResult Factory(string shapeType, Func action) public ShapeAlterationBuilder BoundAs(string bindingSource, Func> bindingDelegate) { + ArgumentException.ThrowIfNullOrEmpty(bindingSource); + // Schedule the configuration. return Configure(descriptor => { diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs index c067db5a492..7359d727291 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Implementation/DefaultHtmlDisplay.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Linq; using System.Threading.Tasks; using Microsoft.AspNetCore.Html; using Microsoft.Extensions.Logging; @@ -14,6 +13,8 @@ namespace OrchardCore.DisplayManagement.Implementation { public class DefaultHtmlDisplay : IHtmlDisplay { + private const string _separator = "__"; + private readonly IShapeTableManager _shapeTableManager; private readonly IEnumerable _shapeDisplayEvents; private readonly IEnumerable _shapeBindingResolvers; @@ -48,7 +49,7 @@ public async Task ExecuteAsync(DisplayContext context) } // Check if the shape is Position Wrapper - if(shape is PositionWrapper wrapper) + if (shape is PositionWrapper wrapper) { return PositionWrapper.UnWrap(wrapper); } @@ -62,7 +63,7 @@ public async Task ExecuteAsync(DisplayContext context) var shapeMetadata = shape.Metadata; // Can't really cope with a shape that has no type information. - if (shapeMetadata == null || string.IsNullOrEmpty(shapeMetadata.Type)) + if (string.IsNullOrEmpty(shapeMetadata?.Type)) { return new HtmlContentString(context.Value.ToString()); } @@ -71,7 +72,7 @@ public async Task ExecuteAsync(DisplayContext context) // for instance to change the HtmlFieldPrefix. var localContext = new DisplayContext(context) { - HtmlFieldPrefix = shapeMetadata.Prefix ?? "", + HtmlFieldPrefix = shapeMetadata.Prefix ?? string.Empty, }; var displayContext = new ShapeDisplayContext @@ -123,17 +124,12 @@ public async Task ExecuteAsync(DisplayContext context) } // Now find the actual binding to render, taking alternates into account. - var actualBinding = await GetShapeBindingAsync(shapeMetadata.Type, shapeMetadata.Alternates, shapeTable); - if (actualBinding != null) - { - await shapeMetadata.ProcessingAsync.InvokeAsync((action, displayContext) => action(displayContext.Shape), displayContext, _logger); + var actualBinding = await GetShapeBindingAsync(shapeMetadata.Type, shapeMetadata.Alternates, shapeTable) + ?? throw new Exception($"The shape type '{shapeMetadata.Type}' is not found"); - shape.Metadata.ChildContent = await ProcessAsync(actualBinding, shape, localContext); - } - else - { - throw new Exception($"Shape type '{shapeMetadata.Type}' not found"); - } + await shapeMetadata.ProcessingAsync.InvokeAsync((action, displayContext) => action(displayContext.Shape), displayContext, _logger); + + shape.Metadata.ChildContent = await ProcessAsync(actualBinding, shape, localContext); } // Process wrappers. @@ -202,7 +198,7 @@ private static ShapeDescriptor GetShapeDescriptor(string shapeType, ShapeTable s if (!shapeTable.Descriptors.TryGetValue(shapeType, out var shapeDescriptor)) { // Check if not a fundamental type. - var index = shapeType.IndexOf("__", StringComparison.Ordinal); + var index = shapeType.IndexOf(_separator, StringComparison.Ordinal); if (index > 0) { @@ -241,8 +237,8 @@ private async Task GetShapeBindingAsync(string shapeType, Alternat } // When no alternates matches, the shapeType is used to find the longest matching binding, - // the shapetype name can break itself into shorter fallbacks at double-underscore marks, - // so the shapetype itself may contain a longer alternate forms that falls back to a shorter one. + // the shape-type name can break itself into shorter fallbacks at double-underscore marks, + // so the shape-type itself may contain a longer alternate forms that falls back to a shorter one. var shapeTypeScan = shapeType; do @@ -269,7 +265,7 @@ private async Task GetShapeBindingAsync(string shapeType, Alternat private static bool TryGetParentShapeTypeName(ref string shapeTypeScan) { - var delimiterIndex = shapeTypeScan.LastIndexOf("__", StringComparison.Ordinal); + var delimiterIndex = shapeTypeScan.LastIndexOf(_separator, StringComparison.Ordinal); if (delimiterIndex > 0) { shapeTypeScan = shapeTypeScan[..delimiterIndex]; diff --git a/src/OrchardCore/OrchardCore.DisplayManagement/Views/ShapeViewModel.cs b/src/OrchardCore/OrchardCore.DisplayManagement/Views/ShapeViewModel.cs index 33305412241..0036c50b116 100644 --- a/src/OrchardCore/OrchardCore.DisplayManagement/Views/ShapeViewModel.cs +++ b/src/OrchardCore/OrchardCore.DisplayManagement/Views/ShapeViewModel.cs @@ -2,7 +2,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; -using Microsoft.AspNetCore.Html; using OrchardCore.DisplayManagement.Shapes; using OrchardCore.DisplayManagement.Zones; @@ -83,7 +82,10 @@ public ValueTask AddAsync(object item, string position) var wrapped = PositionWrapper.TryWrap(item, position); if (wrapped is not null) + { _items.Add(wrapped); + } + return new ValueTask(this); } }