diff --git a/Extensions/CodeGeneration/CodeGenerationDisplayDriver.cs b/Extensions/CodeGeneration/CodeGenerationDisplayDriver.cs index a37fbf6f..83ea7d58 100644 --- a/Extensions/CodeGeneration/CodeGenerationDisplayDriver.cs +++ b/Extensions/CodeGeneration/CodeGenerationDisplayDriver.cs @@ -6,235 +6,240 @@ using OrchardCore.DisplayManagement.Views; using System; using System.Collections.Generic; +using System.Globalization; using System.Linq; using System.Text; -namespace Lombiq.HelpfulExtensions.Extensions.CodeGeneration +namespace Lombiq.HelpfulExtensions.Extensions.CodeGeneration; + +public class CodeGenerationDisplayDriver : ContentTypeDefinitionDisplayDriver { - public class CodeGenerationDisplayDriver : ContentTypeDefinitionDisplayDriver - { - private readonly IStringLocalizer T; + private readonly IStringLocalizer T; - public CodeGenerationDisplayDriver(IStringLocalizer stringLocalizer) => - T = stringLocalizer; + public CodeGenerationDisplayDriver(IStringLocalizer stringLocalizer) => + T = stringLocalizer; - public override IDisplayResult Edit(ContentTypeDefinition model) => - Initialize( - "ContentTypeMigrations_Edit", - viewModel => viewModel.MigrationCodeLazy = new Lazy(() => - { - var codeBuilder = new StringBuilder(); + public override IDisplayResult Edit(ContentTypeDefinition model) => + Initialize( + "ContentTypeMigrations_Edit", + viewModel => viewModel.MigrationCodeLazy = new Lazy(() => + { + var codeBuilder = new StringBuilder(); - // Building the code for the type. - var name = model.Name; - codeBuilder.AppendLine($"_contentDefinitionManager.AlterTypeDefinition(\"{name}\", type => type"); - codeBuilder.AppendLine($" .DisplayedAs(\"{model.DisplayName}\")"); + // Building the code for the type. + var name = model.Name; - GenerateCodeForSettings(codeBuilder, model.GetSettings()); - AddSettingsWithout(codeBuilder, model.Settings, 4); - GenerateCodeForParts(codeBuilder, model.Parts); - codeBuilder.AppendLine(");"); + // This would be great in a Helpful Libraries extension method but unless we construct and manage an + // StringBuilder.AppendInterpolatedStringHandler instance by hand (to be able to use pass on a + // FormattableString received from here to StringBuilder.AppendLine(IFormatProvider? provider, ref + // AppendInterpolatedStringHandler handler)) it won't work. + codeBuilder.AppendLine(CultureInfo.InvariantCulture, $"_contentDefinitionManager.AlterTypeDefinition(\"{name}\", type => type"); + codeBuilder.AppendLine(CultureInfo.InvariantCulture, $" .DisplayedAs(\"{model.DisplayName}\")"); - GenerateCodeForPartsWithFields(codeBuilder, model.Parts); + GenerateCodeForSettings(codeBuilder, model.GetSettings()); + AddSettingsWithout(codeBuilder, model.Settings, 4); + GenerateCodeForParts(codeBuilder, model.Parts); + codeBuilder.AppendLine(");"); + + GenerateCodeForPartsWithFields(codeBuilder, model.Parts); - return codeBuilder.ToString(); - })) - .Location("Content:7"); + return codeBuilder.ToString(); + })) + .Location("Content:7"); - private void GenerateCodeForParts(StringBuilder codeBuilder, IEnumerable parts) + private void GenerateCodeForParts(StringBuilder codeBuilder, IEnumerable parts) + { + foreach (var part in parts) { - foreach (var part in parts) - { - var partSettings = part.GetSettings(); + var partSettings = part.GetSettings(); - codeBuilder.AppendLine($" .WithPart(\"{part.Name}\", part => part"); + codeBuilder.AppendLine(CultureInfo.InvariantCulture, $" .WithPart(\"{part.Name}\", part => part"); - var partStartingLength = codeBuilder.Length; + var partStartingLength = codeBuilder.Length; - AddWithLine(codeBuilder, nameof(partSettings.DisplayName), partSettings.DisplayName); - AddWithLine(codeBuilder, nameof(partSettings.Description), partSettings.Description); - AddWithLine(codeBuilder, nameof(partSettings.Position), partSettings.Position); - AddWithLine(codeBuilder, nameof(partSettings.DisplayMode), partSettings.DisplayMode); - AddWithLine(codeBuilder, nameof(partSettings.Editor), partSettings.Editor); + AddWithLine(codeBuilder, nameof(partSettings.DisplayName), partSettings.DisplayName); + AddWithLine(codeBuilder, nameof(partSettings.Description), partSettings.Description); + AddWithLine(codeBuilder, nameof(partSettings.Position), partSettings.Position); + AddWithLine(codeBuilder, nameof(partSettings.DisplayMode), partSettings.DisplayMode); + AddWithLine(codeBuilder, nameof(partSettings.Editor), partSettings.Editor); - AddSettingsWithout(codeBuilder, part.Settings, 8); + AddSettingsWithout(codeBuilder, part.Settings, 8); - // Checking if anything was added to the part's settings. - if (codeBuilder.Length == partStartingLength) - { - // Remove ", part => part" and the line break. - codeBuilder.Length -= 16; - codeBuilder.Append(")" + Environment.NewLine); - } - else - { - codeBuilder.AppendLine(" )"); - } + // Checking if anything was added to the part's settings. + if (codeBuilder.Length == partStartingLength) + { + // Remove ", part => part" and the line break. + codeBuilder.Length -= 16; + codeBuilder.Append(")" + Environment.NewLine); + } + else + { + codeBuilder.AppendLine(" )"); } } + } - /// - /// Building those parts that have fields separately (fields can't be configured inline in types). - /// - private void GenerateCodeForPartsWithFields( - StringBuilder codeBuilder, - IEnumerable parts) + /// + /// Building those parts that have fields separately (fields can't be configured inline in types). + /// + private void GenerateCodeForPartsWithFields( + StringBuilder codeBuilder, + IEnumerable parts) + { + var partDefinitions = parts + .Where(part => part.PartDefinition.Fields.Any()) + .Select(part => part.PartDefinition); + foreach (var part in partDefinitions) { - var partDefinitions = parts - .Where(part => part.PartDefinition.Fields.Any()) - .Select(part => part.PartDefinition); - foreach (var part in partDefinitions) - { - codeBuilder.AppendLine(); - codeBuilder.AppendLine($"_contentDefinitionManager.AlterPartDefinition(\"{part.Name}\", part => part"); + codeBuilder.AppendLine(); + codeBuilder.AppendLine(CultureInfo.InvariantCulture, $"_contentDefinitionManager.AlterPartDefinition(\"{part.Name}\", part => part"); - var partSettings = part.GetSettings(); - if (partSettings.Attachable) codeBuilder.AppendLine(" .Attachable()"); - if (partSettings.Reusable) codeBuilder.AppendLine(" .Reusable()"); + var partSettings = part.GetSettings(); + if (partSettings.Attachable) codeBuilder.AppendLine(" .Attachable()"); + if (partSettings.Reusable) codeBuilder.AppendLine(" .Reusable()"); - AddWithLine(codeBuilder, nameof(partSettings.DisplayName), partSettings.DisplayName); - AddWithLine(codeBuilder, nameof(partSettings.Description), partSettings.Description); - AddWithLine(codeBuilder, nameof(partSettings.DefaultPosition), partSettings.DefaultPosition); + AddWithLine(codeBuilder, nameof(partSettings.DisplayName), partSettings.DisplayName); + AddWithLine(codeBuilder, nameof(partSettings.Description), partSettings.Description); + AddWithLine(codeBuilder, nameof(partSettings.DefaultPosition), partSettings.DefaultPosition); - AddSettingsWithout(codeBuilder, part.Settings, 4); + AddSettingsWithout(codeBuilder, part.Settings, 4); - foreach (var field in part.Fields) - { - codeBuilder.AppendLine($" .WithField(\"{field.Name}\", field => field"); - codeBuilder.AppendLine($" .OfType(\"{field.FieldDefinition.Name}\")"); - - var fieldSettings = field.GetSettings(); - AddWithLine(codeBuilder, nameof(fieldSettings.DisplayName), fieldSettings.DisplayName); - AddWithLine(codeBuilder, nameof(fieldSettings.Description), fieldSettings.Description); - AddWithLine(codeBuilder, nameof(fieldSettings.Editor), fieldSettings.Editor); - AddWithLine(codeBuilder, nameof(fieldSettings.DisplayMode), fieldSettings.DisplayMode); - AddWithLine(codeBuilder, nameof(fieldSettings.Position), fieldSettings.Position); + foreach (var field in part.Fields) + { + codeBuilder.AppendLine(CultureInfo.InvariantCulture, $" .WithField(\"{field.Name}\", field => field"); + codeBuilder.AppendLine(CultureInfo.InvariantCulture, $" .OfType(\"{field.FieldDefinition.Name}\")"); - AddSettingsWithout(codeBuilder, field.Settings, 8); + var fieldSettings = field.GetSettings(); + AddWithLine(codeBuilder, nameof(fieldSettings.DisplayName), fieldSettings.DisplayName); + AddWithLine(codeBuilder, nameof(fieldSettings.Description), fieldSettings.Description); + AddWithLine(codeBuilder, nameof(fieldSettings.Editor), fieldSettings.Editor); + AddWithLine(codeBuilder, nameof(fieldSettings.DisplayMode), fieldSettings.DisplayMode); + AddWithLine(codeBuilder, nameof(fieldSettings.Position), fieldSettings.Position); - codeBuilder.AppendLine(" )"); - } + AddSettingsWithout(codeBuilder, field.Settings, 8); - codeBuilder.AppendLine(");"); + codeBuilder.AppendLine(" )"); } - } - private string ConvertJToken(JToken jToken, int indentationDepth) - { - switch (jToken) - { - case JValue jValue: - var value = jValue.Value; - return value switch - { - bool boolValue => boolValue ? "true" : "false", - string => $"\"{value}\"", - _ => value?.ToString()?.Replace(',', '.'), // Replace decimal commas. - }; - - case JArray jArray: - var indentation = new string(' ', indentationDepth + 4); - - var items = jArray.Select(item => ConvertJToken(item, indentationDepth + 8)).ToList(); - - // If the items are formatted (for ListValueOption) then don't inject line-by-line formatting. - if (items.Any(item => item.ContainsOrdinalIgnoreCase(Environment.NewLine))) - { - var token = string.Join(string.Empty, items); - return $"new[]\n{indentation}{{\n{token}{indentation}}}"; - } - - // Otherwise, make sure that we have proper formatting for string arrays. - var stringArrayCodeBuilder = new StringBuilder("new[]"); - stringArrayCodeBuilder.AppendLine(); - stringArrayCodeBuilder.AppendLine($"{indentation}{{"); - - var itemIndentation = new string(' ', indentationDepth + 8); - - foreach (var item in items) - { - stringArrayCodeBuilder.AppendLine($"{itemIndentation}{item},"); - } - - stringArrayCodeBuilder.Append($"{indentation}}}"); - - return stringArrayCodeBuilder.ToString(); - - case JObject jObject: - var braceIndentation = new string(' ', indentationDepth); - var propertyIndentation = new string(' ', indentationDepth + 4); - if (jObject["name"] != null && jObject["value"] != null) - { - var objectCodeBuilder = new StringBuilder(); - objectCodeBuilder.AppendLine($"{braceIndentation}new ListValueOption"); - objectCodeBuilder.AppendLine($"{braceIndentation}{{"); - objectCodeBuilder.AppendLine($"{propertyIndentation}Name = \"{jObject["name"]}\","); - objectCodeBuilder.AppendLine($"{propertyIndentation}Value = \"{jObject["value"]}\","); - objectCodeBuilder.AppendLine($"{braceIndentation}}},"); - - return objectCodeBuilder.ToString(); - } - - // Using a quoted string so it doesn't mess up the syntax highlighting of the rest of the code. - return T["\"FIX ME! Couldn't determine the actual type to instantiate.\" {0}", jObject.ToString()]; - - default: - throw new NotSupportedException($"Settings values of type {jToken.GetType()} are not supported."); - } + codeBuilder.AppendLine(");"); } + } - private void AddSettingsWithout(StringBuilder codeBuilder, JObject settings, int indentationDepth) + private string ConvertJToken(JToken jToken, int indentationDepth) + { + switch (jToken) { - var indentation = new string(' ', indentationDepth); + case JValue jValue: + var value = jValue.Value; + return value switch + { + bool boolValue => boolValue ? "true" : "false", + string => $"\"{value}\"", + _ => value?.ToString()?.Replace(',', '.'), // Replace decimal commas. + }; - var filteredSettings = ((IEnumerable>)settings) - .Where(setting => setting.Key != typeof(T).Name); + case JArray jArray: + var indentation = new string(' ', indentationDepth + 4); - foreach (var setting in filteredSettings) - { - var properties = setting.Value.Where(property => property is JProperty).Cast().ToArray(); + var items = jArray.Select(item => ConvertJToken(item, indentationDepth + 8)).ToList(); + + // If the items are formatted (for ListValueOption) then don't inject line-by-line formatting. + if (items.Any(item => item.ContainsOrdinalIgnoreCase(Environment.NewLine))) + { + var token = string.Join(string.Empty, items); + return $"new[]\n{indentation}{{\n{token}{indentation}}}"; + } - if (properties.Length == 0) continue; + // Otherwise, make sure that we have proper formatting for string arrays. + var stringArrayCodeBuilder = new StringBuilder("new[]"); + stringArrayCodeBuilder.AppendLine(); + stringArrayCodeBuilder.AppendLine(CultureInfo.InvariantCulture, $"{indentation}{{"); - codeBuilder.AppendLine($"{indentation}.WithSettings(new {setting.Key}"); - codeBuilder.AppendLine(indentation + "{"); + var itemIndentation = new string(' ', indentationDepth + 8); - // This doesn't support multi-level object hierarchies for settings but come on, who uses complex - // settings objects? - for (int i = 0; i < properties.Length; i++) + foreach (var item in items) { - var property = properties[i]; + stringArrayCodeBuilder.AppendLine(CultureInfo.InvariantCulture, $"{itemIndentation}{item},"); + } - var propertyValue = ConvertJToken(property.Value, indentationDepth); + stringArrayCodeBuilder.Append(CultureInfo.InvariantCulture, $"{indentation}}}"); - propertyValue ??= "\"\""; + return stringArrayCodeBuilder.ToString(); - codeBuilder.AppendLine($"{indentation} {property.Name} = {propertyValue},"); + case JObject jObject: + var braceIndentation = new string(' ', indentationDepth); + var propertyIndentation = new string(' ', indentationDepth + 4); + if (jObject["name"] != null && jObject["value"] != null) + { + var objectCodeBuilder = new StringBuilder(); + objectCodeBuilder.AppendLine(CultureInfo.InvariantCulture, $"{braceIndentation}new ListValueOption"); + objectCodeBuilder.AppendLine(CultureInfo.InvariantCulture, $"{braceIndentation}{{"); + objectCodeBuilder.AppendLine(CultureInfo.InvariantCulture, $"{propertyIndentation}Name = \"{jObject["name"]}\","); + objectCodeBuilder.AppendLine(CultureInfo.InvariantCulture, $"{propertyIndentation}Value = \"{jObject["value"]}\","); + objectCodeBuilder.AppendLine(CultureInfo.InvariantCulture, $"{braceIndentation}}},"); + + return objectCodeBuilder.ToString(); } - codeBuilder.AppendLine(indentation + "})"); - } + // Using a quoted string so it doesn't mess up the syntax highlighting of the rest of the code. + return T["\"FIX ME! Couldn't determine the actual type to instantiate.\" {0}", jObject.ToString()]; + + default: + throw new NotSupportedException($"Settings values of type {jToken.GetType()} are not supported."); } + } + + private void AddSettingsWithout(StringBuilder codeBuilder, JObject settings, int indentationDepth) + { + var indentation = new string(' ', indentationDepth); - private static void GenerateCodeForSettings(StringBuilder codeBuilder, ContentTypeSettings contentTypeSettings) + var filteredSettings = ((IEnumerable>)settings) + .Where(setting => setting.Key != typeof(T).Name); + + foreach (var setting in filteredSettings) { - if (contentTypeSettings.Creatable) codeBuilder.AppendLine(" .Creatable()"); - if (contentTypeSettings.Listable) codeBuilder.AppendLine(" .Listable()"); - if (contentTypeSettings.Draftable) codeBuilder.AppendLine(" .Draftable()"); - if (contentTypeSettings.Versionable) codeBuilder.AppendLine(" .Versionable()"); - if (contentTypeSettings.Securable) codeBuilder.AppendLine(" .Securable()"); - if (!string.IsNullOrEmpty(contentTypeSettings.Stereotype)) + var properties = setting.Value.Where(property => property is JProperty).Cast().ToArray(); + + if (properties.Length == 0) continue; + + codeBuilder.AppendLine(CultureInfo.InvariantCulture, $"{indentation}.WithSettings(new {setting.Key}"); + codeBuilder.AppendLine(indentation + "{"); + + // This doesn't support multi-level object hierarchies for settings but come on, who uses complex settings + // objects? + for (int i = 0; i < properties.Length; i++) { - codeBuilder.AppendLine($" .Stereotype(\"{contentTypeSettings.Stereotype}\")"); + var property = properties[i]; + + var propertyValue = ConvertJToken(property.Value, indentationDepth); + + propertyValue ??= "\"\""; + + codeBuilder.AppendLine(CultureInfo.InvariantCulture, $"{indentation} {property.Name} = {propertyValue},"); } + + codeBuilder.AppendLine(indentation + "})"); + } + } + + private static void GenerateCodeForSettings(StringBuilder codeBuilder, ContentTypeSettings contentTypeSettings) + { + if (contentTypeSettings.Creatable) codeBuilder.AppendLine(" .Creatable()"); + if (contentTypeSettings.Listable) codeBuilder.AppendLine(" .Listable()"); + if (contentTypeSettings.Draftable) codeBuilder.AppendLine(" .Draftable()"); + if (contentTypeSettings.Versionable) codeBuilder.AppendLine(" .Versionable()"); + if (contentTypeSettings.Securable) codeBuilder.AppendLine(" .Securable()"); + if (!string.IsNullOrEmpty(contentTypeSettings.Stereotype)) + { + codeBuilder.AppendLine(CultureInfo.InvariantCulture, $" .Stereotype(\"{contentTypeSettings.Stereotype}\")"); } + } - private static void AddWithLine(StringBuilder codeBuilder, string name, string value) + private static void AddWithLine(StringBuilder codeBuilder, string name, string value) + { + if (!string.IsNullOrEmpty(value)) { - if (!string.IsNullOrEmpty(value)) - { - codeBuilder.AppendLine($" .With{name}(\"{value}\")"); - } + codeBuilder.AppendLine(CultureInfo.InvariantCulture, $" .With{name}(\"{value}\")"); } } } diff --git a/Extensions/CodeGeneration/ContentTypeMigrationsViewModel.cs b/Extensions/CodeGeneration/ContentTypeMigrationsViewModel.cs index b255f379..8fe760b5 100644 --- a/Extensions/CodeGeneration/ContentTypeMigrationsViewModel.cs +++ b/Extensions/CodeGeneration/ContentTypeMigrationsViewModel.cs @@ -1,10 +1,9 @@ using System; -namespace Lombiq.HelpfulExtensions.Extensions.CodeGeneration +namespace Lombiq.HelpfulExtensions.Extensions.CodeGeneration; + +public class ContentTypeMigrationsViewModel { - public class ContentTypeMigrationsViewModel - { - internal Lazy MigrationCodeLazy { get; set; } - public string MigrationCode => MigrationCodeLazy.Value; - } + internal Lazy MigrationCodeLazy { get; set; } + public string MigrationCode => MigrationCodeLazy.Value; } diff --git a/Extensions/CodeGeneration/Startup.cs b/Extensions/CodeGeneration/Startup.cs index 3dff33fc..e3ad74d3 100644 --- a/Extensions/CodeGeneration/Startup.cs +++ b/Extensions/CodeGeneration/Startup.cs @@ -5,17 +5,16 @@ using OrchardCore.Modules; using System; -namespace Lombiq.HelpfulExtensions.Extensions.CodeGeneration +namespace Lombiq.HelpfulExtensions.Extensions.CodeGeneration; + +[Feature(FeatureIds.CodeGeneration)] +public class Startup : StartupBase { - [Feature(FeatureIds.CodeGeneration)] - public class Startup : StartupBase - { - public override void ConfigureServices(IServiceCollection services) => - services.AddScoped(); + public override void ConfigureServices(IServiceCollection services) => + services.AddScoped(); - public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) - { - // No need for anything here yet. - } + public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) + { + // No need for anything here yet. } } diff --git a/Extensions/ContentTypes/ContentTypes.cs b/Extensions/ContentTypes/ContentTypes.cs index 62cf020e..aa6f2fbd 100644 --- a/Extensions/ContentTypes/ContentTypes.cs +++ b/Extensions/ContentTypes/ContentTypes.cs @@ -1,7 +1,6 @@ -namespace Lombiq.HelpfulExtensions.Extensions.ContentTypes +namespace Lombiq.HelpfulExtensions.Extensions.ContentTypes; + +public static class ContentTypes { - public static class ContentTypes - { - public const string Page = nameof(Page); - } + public const string Page = nameof(Page); } diff --git a/Extensions/ContentTypes/Migrations.cs b/Extensions/ContentTypes/Migrations.cs index e6dd25a1..9674e661 100644 --- a/Extensions/ContentTypes/Migrations.cs +++ b/Extensions/ContentTypes/Migrations.cs @@ -4,47 +4,46 @@ using OrchardCore.Data.Migration; using static Lombiq.HelpfulExtensions.Extensions.ContentTypes.ContentTypes; -namespace Lombiq.HelpfulExtensions.Extensions.ContentTypes +namespace Lombiq.HelpfulExtensions.Extensions.ContentTypes; + +public class Migrations : DataMigration { - public class Migrations : DataMigration - { - private readonly IContentDefinitionManager _contentDefinitionManager; + private readonly IContentDefinitionManager _contentDefinitionManager; - public Migrations(IContentDefinitionManager contentDefinitionManager) => - _contentDefinitionManager = contentDefinitionManager; + public Migrations(IContentDefinitionManager contentDefinitionManager) => + _contentDefinitionManager = contentDefinitionManager; - public int Create() - { - _contentDefinitionManager.AlterTypeDefinition(Page, builder => builder - .Creatable() - .Securable() - .Draftable() - .Listable() - .Versionable() - .WithPart("TitlePart", part => part.WithPosition("0")) - .WithPart("AutoroutePart", part => part - .WithPosition("1") - .WithSettings(new AutoroutePartSettings - { - ShowHomepageOption = true, - AllowCustomPath = true, - }) - ) - .WithPart("FlowPart", part => part.WithPosition("2")) - ); + public int Create() + { + _contentDefinitionManager.AlterTypeDefinition(Page, builder => builder + .Creatable() + .Securable() + .Draftable() + .Listable() + .Versionable() + .WithPart("TitlePart", part => part.WithPosition("0")) + .WithPart("AutoroutePart", part => part + .WithPosition("1") + .WithSettings(new AutoroutePartSettings + { + ShowHomepageOption = true, + AllowCustomPath = true, + }) + ) + .WithPart("FlowPart", part => part.WithPosition("2")) + ); - return 2; - } + return 2; + } - public int UpdateFrom1() - { - _contentDefinitionManager.AlterTypeDefinition(Page, builder => builder - .WithPart("TitlePart", part => part.WithPosition("0")) - .WithPart("AutoroutePart", part => part.WithPosition("1")) - .WithPart("FlowPart", part => part.WithPosition("2")) - ); + public int UpdateFrom1() + { + _contentDefinitionManager.AlterTypeDefinition(Page, builder => builder + .WithPart("TitlePart", part => part.WithPosition("0")) + .WithPart("AutoroutePart", part => part.WithPosition("1")) + .WithPart("FlowPart", part => part.WithPosition("2")) + ); - return 2; - } + return 2; } } diff --git a/Extensions/ContentTypes/Startup.cs b/Extensions/ContentTypes/Startup.cs index b00acbce..36033547 100644 --- a/Extensions/ContentTypes/Startup.cs +++ b/Extensions/ContentTypes/Startup.cs @@ -5,16 +5,15 @@ using OrchardCore.Modules; using System; -namespace Lombiq.HelpfulExtensions.Extensions.ContentTypes +namespace Lombiq.HelpfulExtensions.Extensions.ContentTypes; + +[Feature(FeatureIds.ContentTypes)] +public class Startup : StartupBase { - [Feature(FeatureIds.ContentTypes)] - public class Startup : StartupBase - { - public override void ConfigureServices(IServiceCollection services) => services.AddScoped(); + public override void ConfigureServices(IServiceCollection services) => services.AddScoped(); - public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) - { - // No need for anything here yet. - } + public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) + { + // No need for anything here yet. } } diff --git a/Extensions/Emails/Extensions/EmailSenderShellScopeExtensions.cs b/Extensions/Emails/Extensions/EmailSenderShellScopeExtensions.cs index 7f7fc579..06b58528 100644 --- a/Extensions/Emails/Extensions/EmailSenderShellScopeExtensions.cs +++ b/Extensions/Emails/Extensions/EmailSenderShellScopeExtensions.cs @@ -1,41 +1,40 @@ -using System.Collections.Generic; -using System.Linq; using Lombiq.HelpfulExtensions.Extensions.Emails.Models; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging; using OrchardCore.Email; using OrchardCore.Environment.Shell.Scope; +using System.Collections.Generic; +using System.Linq; -namespace Lombiq.HelpfulExtensions.Extensions.Emails.Extensions +namespace Lombiq.HelpfulExtensions.Extensions.Emails.Extensions; + +public static class EmailSenderShellScopeExtensions { - public static class EmailSenderShellScopeExtensions - { - /// - /// Sends an HTML email after the current shell scope has ended. If any errors occur during the process they - /// will be logged. - /// - /// Parameters required for sending emails (e.g., recipients, subject, CC). - public static void SendEmailDeferred(this ShellScope shellScope, EmailParameters parameters) => - shellScope.AddDeferredTask(async scope => + /// + /// Sends an HTML email after the current shell scope has ended. If any errors occur during the process they will be + /// logged. + /// + /// Parameters required for sending emails (e.g., recipients, subject, CC). + public static void SendEmailDeferred(this ShellScope shellScope, EmailParameters parameters) => + shellScope.AddDeferredTask(async scope => + { + var smtpService = scope.ServiceProvider.GetRequiredService(); + var result = await smtpService.SendAsync(new MailMessage { - var smtpService = scope.ServiceProvider.GetService(); - var result = await smtpService.SendAsync(new MailMessage - { - Sender = parameters.Sender, - To = parameters.To?.Join(","), - Cc = parameters.Cc?.Join(","), - Bcc = parameters.Bcc?.Join(","), - Subject = parameters.Subject, - ReplyTo = parameters.ReplyTo, - Body = parameters.Body, - IsBodyHtml = true, - }); - - if (!result.Succeeded) - { - var logger = scope.ServiceProvider.GetService>(); - logger.LogError("Email sending was unsuccessful: {0}", result.Errors.Select(error => error.ToString()).Join()); - } + Sender = parameters.Sender, + To = parameters.To?.Join(","), + Cc = parameters.Cc?.Join(","), + Bcc = parameters.Bcc?.Join(","), + Subject = parameters.Subject, + ReplyTo = parameters.ReplyTo, + Body = parameters.Body, + IsBodyHtml = true, }); - } + + if (!result.Succeeded) + { + var logger = scope.ServiceProvider.GetRequiredService>(); + logger.LogError("Email sending was unsuccessful: {Error}", result.Errors.Select(error => error.ToString()).Join()); + } + }); } diff --git a/Extensions/Emails/Models/EmailParameters.cs b/Extensions/Emails/Models/EmailParameters.cs index 0c6ad2c7..bcb02b7c 100644 --- a/Extensions/Emails/Models/EmailParameters.cs +++ b/Extensions/Emails/Models/EmailParameters.cs @@ -1,15 +1,14 @@ using System.Collections.Generic; -namespace Lombiq.HelpfulExtensions.Extensions.Emails.Models +namespace Lombiq.HelpfulExtensions.Extensions.Emails.Models; + +public class EmailParameters { - public class EmailParameters - { - public string Sender { get; set; } - public IEnumerable To { get; set; } - public IEnumerable Cc { get; set; } - public IEnumerable Bcc { get; set; } - public string Subject { get; set; } - public string Body { get; set; } - public string ReplyTo { get; set; } - } + public string Sender { get; set; } + public IEnumerable To { get; set; } + public IEnumerable Cc { get; set; } + public IEnumerable Bcc { get; set; } + public string Subject { get; set; } + public string Body { get; set; } + public string ReplyTo { get; set; } } diff --git a/Extensions/Emails/Services/IEmailTemplateService.cs b/Extensions/Emails/Services/IEmailTemplateService.cs index 29366a0d..a3930dfa 100644 --- a/Extensions/Emails/Services/IEmailTemplateService.cs +++ b/Extensions/Emails/Services/IEmailTemplateService.cs @@ -1,18 +1,17 @@ using System.Threading.Tasks; -namespace Lombiq.HelpfulExtensions.Extensions.Emails.Services +namespace Lombiq.HelpfulExtensions.Extensions.Emails.Services; + +/// +/// Service for managing email templates. +/// +public interface IEmailTemplateService { /// - /// Service for managing email templates. + /// Renders an email template content identified by its ID. /// - public interface IEmailTemplateService - { - /// - /// Renders an email template content identified by its ID. - /// - /// ID of the email template. - /// Optional model used as replacements in the email template. - /// Rendered email template. - Task RenderEmailTemplateAsync(string emailTemplateId, object model = null); - } + /// ID of the email template. + /// Optional model used as replacements in the email template. + /// Rendered email template. + Task RenderEmailTemplateAsync(string emailTemplateId, object model = null); } diff --git a/Extensions/Emails/Services/ShapeBasedEmailTemplateService.cs b/Extensions/Emails/Services/ShapeBasedEmailTemplateService.cs index 0ae524a5..39e21e28 100644 --- a/Extensions/Emails/Services/ShapeBasedEmailTemplateService.cs +++ b/Extensions/Emails/Services/ShapeBasedEmailTemplateService.cs @@ -1,28 +1,27 @@ -using System.Threading.Tasks; using Lombiq.HelpfulLibraries.Libraries.Shapes; using Lombiq.HelpfulLibraries.Libraries.Utilities; using OrchardCore.DisplayManagement; +using System.Threading.Tasks; -namespace Lombiq.HelpfulExtensions.Extensions.Emails.Services +namespace Lombiq.HelpfulExtensions.Extensions.Emails.Services; + +public class ShapeBasedEmailTemplateService : IEmailTemplateService { - public class ShapeBasedEmailTemplateService : IEmailTemplateService - { - private readonly IShapeFactory _shapeFactory; - private readonly IShapeRenderer _shapeRenderer; + private readonly IShapeFactory _shapeFactory; + private readonly IShapeRenderer _shapeRenderer; - public ShapeBasedEmailTemplateService(IShapeFactory shapeFactory, IShapeRenderer shapeRenderer) - { - _shapeFactory = shapeFactory; - _shapeRenderer = shapeRenderer; - } + public ShapeBasedEmailTemplateService(IShapeFactory shapeFactory, IShapeRenderer shapeRenderer) + { + _shapeFactory = shapeFactory; + _shapeRenderer = shapeRenderer; + } - public async Task RenderEmailTemplateAsync(string emailTemplateId, object model = null) - { - ExceptionHelpers.ThrowIfNull(emailTemplateId, nameof(emailTemplateId)); + public async Task RenderEmailTemplateAsync(string emailTemplateId, object model = null) + { + ExceptionHelpers.ThrowIfNull(emailTemplateId, nameof(emailTemplateId)); - var shape = await _shapeFactory.CreateAsync($"EmailTemplate__{emailTemplateId}", Arguments.From(model ?? new { })); + var shape = await _shapeFactory.CreateAsync($"EmailTemplate__{emailTemplateId}", Arguments.From(model ?? new { })); - return await _shapeRenderer.RenderAsync(shape); - } + return await _shapeRenderer.RenderAsync(shape); } } diff --git a/Extensions/Emails/Startup.cs b/Extensions/Emails/Startup.cs index f12d7e3f..180f39dd 100644 --- a/Extensions/Emails/Startup.cs +++ b/Extensions/Emails/Startup.cs @@ -1,25 +1,24 @@ -using System; using Lombiq.HelpfulExtensions.Extensions.Emails.Services; using Lombiq.HelpfulLibraries.Libraries.Shapes; using Microsoft.AspNetCore.Builder; using Microsoft.AspNetCore.Routing; using Microsoft.Extensions.DependencyInjection; using OrchardCore.Modules; +using System; + +namespace Lombiq.HelpfulExtensions.Extensions.Emails; -namespace Lombiq.HelpfulExtensions.Extensions.Emails +[Feature(FeatureIds.Emails)] +public class Startup : StartupBase { - [Feature(FeatureIds.Emails)] - public class Startup : StartupBase + public override void ConfigureServices(IServiceCollection services) { - public override void ConfigureServices(IServiceCollection services) - { - services.AddShapeRenderer(); - services.AddScoped(); - } + services.AddShapeRenderer(); + services.AddScoped(); + } - public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) - { - // No need for anything here yet. - } + public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) + { + // No need for anything here yet. } } diff --git a/Extensions/Flows/Drivers/AdditionalStylingPartDisplay.cs b/Extensions/Flows/Drivers/AdditionalStylingPartDisplay.cs index 5f8f7c4c..b585f8dd 100644 --- a/Extensions/Flows/Drivers/AdditionalStylingPartDisplay.cs +++ b/Extensions/Flows/Drivers/AdditionalStylingPartDisplay.cs @@ -5,39 +5,38 @@ using OrchardCore.DisplayManagement.Views; using System.Threading.Tasks; -namespace Lombiq.HelpfulExtensions.Extensions.Flows.Drivers +namespace Lombiq.HelpfulExtensions.Extensions.Flows.Drivers; + +public class AdditionalStylingPartDisplay : ContentDisplayDriver { - public class AdditionalStylingPartDisplay : ContentDisplayDriver + public override IDisplayResult Edit(ContentItem model, IUpdateModel updater) => + Initialize( + $"{nameof(AdditionalStylingPart)}_Edit", + viewModel => PopulateViewModel(model, viewModel)) + .Location("Footer:3"); + + public override async Task UpdateAsync(ContentItem model, IUpdateModel updater) { - public override IDisplayResult Edit(ContentItem model, IUpdateModel updater) => - Initialize( - $"{nameof(AdditionalStylingPart)}_Edit", - viewModel => PopulateViewModel(model, viewModel)) - .Location("Footer:3"); + var additionalStylingPart = model.As(); - public override async Task UpdateAsync(ContentItem model, IUpdateModel updater) + if (additionalStylingPart == null) { - var additionalStylingPart = model.As(); + return null; + } - if (additionalStylingPart == null) - { - return null; - } + await model.AlterAsync(model => updater.TryUpdateModelAsync(model, Prefix)); - await model.AlterAsync(model => updater.TryUpdateModelAsync(model, Prefix)); + return await EditAsync(model, updater); + } - return await EditAsync(model, updater); - } + private static void PopulateViewModel(ContentItem model, AdditionalStylingPart viewModel) + { + var additionalStylingPart = model.As(); - private static void PopulateViewModel(ContentItem model, AdditionalStylingPart viewModel) + if (additionalStylingPart != null) { - var additionalStylingPart = model.As(); - - if (additionalStylingPart != null) - { - viewModel.CustomClasses = additionalStylingPart.CustomClasses; - viewModel.RemoveGridExtensionClasses = additionalStylingPart.RemoveGridExtensionClasses; - } + viewModel.CustomClasses = additionalStylingPart.CustomClasses; + viewModel.RemoveGridExtensionClasses = additionalStylingPart.RemoveGridExtensionClasses; } } } diff --git a/Extensions/Flows/FlowPartShapeTableProvider.cs b/Extensions/Flows/FlowPartShapeTableProvider.cs index b6ed48d0..3ad62a58 100644 --- a/Extensions/Flows/FlowPartShapeTableProvider.cs +++ b/Extensions/Flows/FlowPartShapeTableProvider.cs @@ -1,11 +1,10 @@ using OrchardCore.DisplayManagement.Descriptors; -namespace Lombiq.HelpfulExtensions.Extensions.Flows +namespace Lombiq.HelpfulExtensions.Extensions.Flows; + +internal class FlowPartShapeTableProvider : IShapeTableProvider { - internal class FlowPartShapeTableProvider : IShapeTableProvider - { - public void Discover(ShapeTableBuilder builder) => builder - .Describe("FlowPart") - .OnDisplaying(displaying => displaying.Shape.Metadata.Alternates.Add("Lombiq_HelpfulExtensions_Flows_FlowPart")); - } + public void Discover(ShapeTableBuilder builder) => builder + .Describe("FlowPart") + .OnDisplaying(displaying => displaying.Shape.Metadata.Alternates.Add("Lombiq_HelpfulExtensions_Flows_FlowPart")); } diff --git a/Extensions/Flows/Handlers/AdditionalStylingPartHandler.cs b/Extensions/Flows/Handlers/AdditionalStylingPartHandler.cs index 68742248..2912f74b 100644 --- a/Extensions/Flows/Handlers/AdditionalStylingPartHandler.cs +++ b/Extensions/Flows/Handlers/AdditionalStylingPartHandler.cs @@ -5,25 +5,24 @@ using OrchardCore.ContentManagement.Metadata.Settings; using System.Threading.Tasks; -namespace Lombiq.HelpfulExtensions.Extensions.Flows.Handlers +namespace Lombiq.HelpfulExtensions.Extensions.Flows.Handlers; + +public class AdditionalStylingPartHandler : ContentHandlerBase { - public class AdditionalStylingPartHandler : ContentHandlerBase - { - private readonly IContentDefinitionManager _contentDefinitionManager; + private readonly IContentDefinitionManager _contentDefinitionManager; - public AdditionalStylingPartHandler(IContentDefinitionManager contentDefinitionManager) => - _contentDefinitionManager = contentDefinitionManager; + public AdditionalStylingPartHandler(IContentDefinitionManager contentDefinitionManager) => + _contentDefinitionManager = contentDefinitionManager; - public override Task ActivatedAsync(ActivatedContentContext context) + public override Task ActivatedAsync(ActivatedContentContext context) + { + if (!context.ContentItem.Has() && + _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType) + .GetSettings().Stereotype == "Widget") { - if (!context.ContentItem.Has() && - _contentDefinitionManager.GetTypeDefinition(context.ContentItem.ContentType) - .GetSettings().Stereotype == "Widget") - { - context.ContentItem.Weld(); - } - - return Task.CompletedTask; + context.ContentItem.Weld(); } + + return Task.CompletedTask; } } diff --git a/Extensions/Flows/Models/AdditionalStylingPart.cs b/Extensions/Flows/Models/AdditionalStylingPart.cs index 94e18ba9..242fc2ab 100644 --- a/Extensions/Flows/Models/AdditionalStylingPart.cs +++ b/Extensions/Flows/Models/AdditionalStylingPart.cs @@ -1,10 +1,9 @@ using OrchardCore.ContentManagement; -namespace Lombiq.HelpfulExtensions.Extensions.Flows.Models +namespace Lombiq.HelpfulExtensions.Extensions.Flows.Models; + +public class AdditionalStylingPart : ContentPart { - public class AdditionalStylingPart : ContentPart - { - public string CustomClasses { get; set; } - public bool RemoveGridExtensionClasses { get; set; } - } + public string CustomClasses { get; set; } + public bool RemoveGridExtensionClasses { get; set; } } diff --git a/Extensions/Flows/Startup.cs b/Extensions/Flows/Startup.cs index c8df9138..199561ef 100644 --- a/Extensions/Flows/Startup.cs +++ b/Extensions/Flows/Startup.cs @@ -11,22 +11,21 @@ using OrchardCore.Modules; using System; -namespace Lombiq.HelpfulExtensions.Extensions.Flows +namespace Lombiq.HelpfulExtensions.Extensions.Flows; + +[Feature(FeatureIds.Flows)] +public class Startup : StartupBase { - [Feature(FeatureIds.Flows)] - public class Startup : StartupBase + public override void ConfigureServices(IServiceCollection services) { - public override void ConfigureServices(IServiceCollection services) - { - services.AddScoped(); - services.AddScoped(); - services.AddContentPart(); - services.AddScoped(); - } + services.AddScoped(); + services.AddScoped(); + services.AddContentPart(); + services.AddScoped(); + } - public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) - { - // No need for anything here yet. - } + public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) + { + // No need for anything here yet. } } diff --git a/Extensions/Security/Driver/StrictSecuritySettingsDisplayDriver.cs b/Extensions/Security/Driver/StrictSecuritySettingsDisplayDriver.cs index d21440b5..22ccdb6b 100644 --- a/Extensions/Security/Driver/StrictSecuritySettingsDisplayDriver.cs +++ b/Extensions/Security/Driver/StrictSecuritySettingsDisplayDriver.cs @@ -6,31 +6,30 @@ using OrchardCore.DisplayManagement.Views; using System.Threading.Tasks; -namespace Lombiq.HelpfulExtensions.Extensions.Security.Driver -{ - public class StrictSecuritySettingsDisplayDriver : ContentTypeDefinitionDisplayDriver - { - public override IDisplayResult Edit(ContentTypeDefinition model) => - Initialize("StrictSecuritySetting_Edit", viewModel => - { - var settings = model.GetSettings(); +namespace Lombiq.HelpfulExtensions.Extensions.Security.Driver; - viewModel.Enabled = settings?.Enabled == true; - }).Location("Content:5"); - - public override async Task UpdateAsync(ContentTypeDefinition model, UpdateTypeEditorContext context) +public class StrictSecuritySettingsDisplayDriver : ContentTypeDefinitionDisplayDriver +{ + public override IDisplayResult Edit(ContentTypeDefinition model) => + Initialize("StrictSecuritySetting_Edit", viewModel => { - var viewModel = new StrictSecuritySettingsViewModel(); + var settings = model.GetSettings(); - if (await context.Updater.TryUpdateModelAsync(viewModel, Prefix)) - { - // Securable must be enabled for Strict Securable to make sense. Also checked on the client side too. - if (model.GetSettings()?.Securable != true) viewModel.Enabled = false; + viewModel.Enabled = settings?.Enabled == true; + }).Location("Content:5"); - context.Builder.MergeSettings(settings => settings.Enabled = viewModel.Enabled); - } + public override async Task UpdateAsync(ContentTypeDefinition model, UpdateTypeEditorContext context) + { + var viewModel = new StrictSecuritySettingsViewModel(); + + if (await context.Updater.TryUpdateModelAsync(viewModel, Prefix)) + { + // Securable must be enabled for Strict Securable to make sense. Also checked on the client side too. + if (model.GetSettings()?.Securable != true) viewModel.Enabled = false; - return Edit(model); + context.Builder.MergeSettings(settings => settings.Enabled = viewModel.Enabled); } + + return Edit(model); } } diff --git a/Extensions/Security/Models/StrictSecuritySettings.cs b/Extensions/Security/Models/StrictSecuritySettings.cs index 3791a4c5..5f03f9d9 100644 --- a/Extensions/Security/Models/StrictSecuritySettings.cs +++ b/Extensions/Security/Models/StrictSecuritySettings.cs @@ -1,7 +1,6 @@ -namespace Lombiq.HelpfulExtensions.Extensions.Security.Models +namespace Lombiq.HelpfulExtensions.Extensions.Security.Models; + +public class StrictSecuritySettings { - public class StrictSecuritySettings - { - public bool Enabled { get; set; } - } + public bool Enabled { get; set; } } diff --git a/Extensions/Security/Services/StrictSecurityPermissionAuthorizationHandler.cs b/Extensions/Security/Services/StrictSecurityPermissionAuthorizationHandler.cs index 2e7d4526..35a7ff10 100644 --- a/Extensions/Security/Services/StrictSecurityPermissionAuthorizationHandler.cs +++ b/Extensions/Security/Services/StrictSecurityPermissionAuthorizationHandler.cs @@ -11,68 +11,67 @@ using System.Linq; using System.Threading.Tasks; -namespace Lombiq.HelpfulExtensions.Extensions.Security.Services +namespace Lombiq.HelpfulExtensions.Extensions.Security.Services; + +[RequireFeatures(FeatureIds.Security)] +public class StrictSecurityPermissionAuthorizationHandler : AuthorizationHandler { - [RequireFeatures(FeatureIds.Security)] - public class StrictSecurityPermissionAuthorizationHandler : AuthorizationHandler - { - private static readonly Dictionary> _permissionTemplates = ContentTypePermissionsHelper - .PermissionTemplates - .ToDictionary( - pair => pair.Key, - pair => GetPermissionTemplates(pair.Value, new List())); + private static readonly Dictionary> _permissionTemplates = ContentTypePermissionsHelper + .PermissionTemplates + .ToDictionary( + pair => pair.Key, + pair => GetPermissionTemplates(pair.Value, new List())); - private readonly IContentDefinitionManager _contentDefinitionManager; + private readonly IContentDefinitionManager _contentDefinitionManager; - public StrictSecurityPermissionAuthorizationHandler(IContentDefinitionManager contentDefinitionManager) => - _contentDefinitionManager = contentDefinitionManager; + public StrictSecurityPermissionAuthorizationHandler(IContentDefinitionManager contentDefinitionManager) => + _contentDefinitionManager = contentDefinitionManager; - protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, PermissionRequirement requirement) + { + if ((context.Resource as IContent)?.ContentItem is not { } contentItem || + !_permissionTemplates.TryGetValue(requirement.Permission.Name, out var claims) || + _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType) is not { } definition || + definition.GetSettings()?.Enabled != true) { - if ((context.Resource as IContent)?.ContentItem is not { } contentItem || - !_permissionTemplates.TryGetValue(requirement.Permission.Name, out var claims) || - _contentDefinitionManager.GetTypeDefinition(contentItem.ContentType) is not { } definition || - definition.GetSettings()?.Enabled != true) - { - return Task.CompletedTask; - } - - if (!context.User.Identity.IsAuthenticated) - { - context.Fail(); - return Task.CompletedTask; - } - - var contentType = contentItem.ContentType; - claims = claims - .Select(template => string.Format(CultureInfo.InvariantCulture, template, contentType)) - .ToList(); - var permissionNames = context - .User - .Claims - .Where(claim => claim.Type == nameof(Permission)) - .Select(claim => claim.Value); - - if (!permissionNames.Any(claims.Contains)) context.Fail(); return Task.CompletedTask; } - private static IList GetPermissionTemplates(Permission permission, IList templates) + if (!context.User.Identity.IsAuthenticated) { - templates.Add(permission.Name); + context.Fail(); + return Task.CompletedTask; + } + + var contentType = contentItem.ContentType; + claims = claims + .Select(template => string.Format(CultureInfo.InvariantCulture, template, contentType)) + .ToList(); + var permissionNames = context + .User + .Claims + .Where(claim => claim.Type == nameof(Permission)) + .Select(claim => claim.Value); + + if (!permissionNames.Any(claims.Contains)) context.Fail(); + return Task.CompletedTask; + } - if (permission.ImpliedBy is { } impliedBy) + private static IList GetPermissionTemplates(Permission permission, IList templates) + { + templates.Add(permission.Name); + + if (permission.ImpliedBy is { } impliedBy) + { + foreach (var impliedPermission in impliedBy) { - foreach (var impliedPermission in impliedBy) + if (impliedPermission.Name.Contains("{0}")) { - if (impliedPermission.Name.Contains("{0}")) - { - GetPermissionTemplates(impliedPermission, templates); - } + GetPermissionTemplates(impliedPermission, templates); } } - - return templates; } + + return templates; } } diff --git a/Extensions/Security/Startup.cs b/Extensions/Security/Startup.cs index 4bf9077e..651fc43e 100644 --- a/Extensions/Security/Startup.cs +++ b/Extensions/Security/Startup.cs @@ -6,16 +6,15 @@ using OrchardCore.ContentTypes.Editors; using OrchardCore.Modules; -namespace Lombiq.HelpfulExtensions.Extensions.Security +namespace Lombiq.HelpfulExtensions.Extensions.Security; + +[Feature(FeatureIds.Security)] +public class Startup : StartupBase { - [Feature(FeatureIds.Security)] - public class Startup : StartupBase + public override void ConfigureServices(IServiceCollection services) { - public override void ConfigureServices(IServiceCollection services) - { - services.AddLazyInjectionSupport(); - services.AddScoped(); - services.AddScoped(); - } + services.AddLazyInjectionSupport(); + services.AddScoped(); + services.AddScoped(); } } diff --git a/Extensions/Security/ViewModels/StrictSecuritySettingsViewModel.cs b/Extensions/Security/ViewModels/StrictSecuritySettingsViewModel.cs index 9e7b315b..f907829d 100644 --- a/Extensions/Security/ViewModels/StrictSecuritySettingsViewModel.cs +++ b/Extensions/Security/ViewModels/StrictSecuritySettingsViewModel.cs @@ -1,7 +1,6 @@ -namespace Lombiq.HelpfulExtensions.Extensions.Security.ViewModels +namespace Lombiq.HelpfulExtensions.Extensions.Security.ViewModels; + +public class StrictSecuritySettingsViewModel { - public class StrictSecuritySettingsViewModel - { - public bool Enabled { get; set; } - } + public bool Enabled { get; set; } } diff --git a/Extensions/ShapeTracing/ShapeTracingShapeEvents.cs b/Extensions/ShapeTracing/ShapeTracingShapeEvents.cs index 2b6ce41e..b66c6d0e 100644 --- a/Extensions/ShapeTracing/ShapeTracingShapeEvents.cs +++ b/Extensions/ShapeTracing/ShapeTracingShapeEvents.cs @@ -5,78 +5,77 @@ using System.Linq; using System.Threading.Tasks; -namespace Lombiq.HelpfulExtensions.Extensions.ShapeTracing +namespace Lombiq.HelpfulExtensions.Extensions.ShapeTracing; + +internal class ShapeTracingShapeEvents : IShapeDisplayEvents { - internal class ShapeTracingShapeEvents : IShapeDisplayEvents - { - private readonly IHttpContextAccessor _hca; + private readonly IHttpContextAccessor _hca; - public ShapeTracingShapeEvents(IHttpContextAccessor hca) => _hca = hca; + public ShapeTracingShapeEvents(IHttpContextAccessor hca) => _hca = hca; - public Task DisplayedAsync(ShapeDisplayContext context) - { - if (!_hca.HttpContext.IsDevelopment()) return Task.CompletedTask; + public Task DisplayedAsync(ShapeDisplayContext context) + { + if (!_hca.HttpContext.IsDevelopment()) return Task.CompletedTask; - // We could also use _orchardHelper.ConsoleLog(context.Shape) here but that causes an OutOfMemoryException. + // We could also use _orchardHelper.ConsoleLog(context.Shape) here but that causes an OutOfMemoryException. - var builder = new HtmlContentBuilder(6); - var shapeMetadata = context.Shape.Metadata; + var builder = new HtmlContentBuilder(6); + var shapeMetadata = context.Shape.Metadata; - builder.AppendLine(); - builder.AppendHtmlLine(""); + builder.AppendHtmlLine("-->"); - builder.AppendHtml(context.ChildContent); + builder.AppendHtml(context.ChildContent); - context.ChildContent = builder; + context.ChildContent = builder; - return Task.CompletedTask; - } + return Task.CompletedTask; + } - public Task DisplayingAsync(ShapeDisplayContext context) => Task.CompletedTask; + public Task DisplayingAsync(ShapeDisplayContext context) => Task.CompletedTask; - public Task DisplayingFinalizedAsync(ShapeDisplayContext context) => Task.CompletedTask; - } + public Task DisplayingFinalizedAsync(ShapeDisplayContext context) => Task.CompletedTask; } diff --git a/Extensions/ShapeTracing/Startup.cs b/Extensions/ShapeTracing/Startup.cs index e4ea921a..853a7472 100644 --- a/Extensions/ShapeTracing/Startup.cs +++ b/Extensions/ShapeTracing/Startup.cs @@ -2,12 +2,11 @@ using OrchardCore.DisplayManagement.Implementation; using OrchardCore.Modules; -namespace Lombiq.HelpfulExtensions.Extensions.ShapeTracing +namespace Lombiq.HelpfulExtensions.Extensions.ShapeTracing; + +[Feature(FeatureIds.ShapeTracing)] +public class Startup : StartupBase { - [Feature(FeatureIds.ShapeTracing)] - public class Startup : StartupBase - { - public override void ConfigureServices(IServiceCollection services) => - services.AddScoped(); - } + public override void ConfigureServices(IServiceCollection services) => + services.AddScoped(); } diff --git a/Extensions/Widgets/Migrations.cs b/Extensions/Widgets/Migrations.cs index 545b8c50..88aef92c 100644 --- a/Extensions/Widgets/Migrations.cs +++ b/Extensions/Widgets/Migrations.cs @@ -3,70 +3,69 @@ using OrchardCore.Data.Migration; using static Lombiq.HelpfulExtensions.Extensions.Widgets.WidgetTypes; -namespace Lombiq.HelpfulExtensions.Extensions.Widgets +namespace Lombiq.HelpfulExtensions.Extensions.Widgets; + +public class Migrations : DataMigration { - public class Migrations : DataMigration - { - private readonly IContentDefinitionManager _contentDefinitionManager; + private readonly IContentDefinitionManager _contentDefinitionManager; - public Migrations(IContentDefinitionManager contentDefinitionManager) => - _contentDefinitionManager = contentDefinitionManager; + public Migrations(IContentDefinitionManager contentDefinitionManager) => + _contentDefinitionManager = contentDefinitionManager; - public int Create() - { - _contentDefinitionManager.AlterTypeDefinition(ContainerWidget, builder => builder - .Securable() - .Stereotype("Widget") - .WithPart("TitlePart", part => part.WithPosition("0")) - .WithPart("FlowPart", part => part.WithPosition("1")) - ); + public int Create() + { + _contentDefinitionManager.AlterTypeDefinition(ContainerWidget, builder => builder + .Securable() + .Stereotype("Widget") + .WithPart("TitlePart", part => part.WithPosition("0")) + .WithPart("FlowPart", part => part.WithPosition("1")) + ); - _contentDefinitionManager.AlterTypeDefinition(HtmlWidget, builder => builder - .Securable() - .Stereotype("Widget") - .WithPart("HtmlBodyPart", part => part - .WithDisplayName("HTML Body") - .WithSettings(new ContentTypePartSettings - { - Editor = "Trumbowyg", - }) - ) - ); + _contentDefinitionManager.AlterTypeDefinition(HtmlWidget, builder => builder + .Securable() + .Stereotype("Widget") + .WithPart("HtmlBodyPart", part => part + .WithDisplayName("HTML Body") + .WithSettings(new ContentTypePartSettings + { + Editor = "Trumbowyg", + }) + ) + ); - _contentDefinitionManager.AlterTypeDefinition(LiquidWidget, builder => builder - .Securable() - .Stereotype("Widget") - .WithPart("LiquidPart", part => part - .WithDisplayName("Liquid Part") - ) - ); + _contentDefinitionManager.AlterTypeDefinition(LiquidWidget, builder => builder + .Securable() + .Stereotype("Widget") + .WithPart("LiquidPart", part => part + .WithDisplayName("Liquid Part") + ) + ); - _contentDefinitionManager.AlterTypeDefinition(MenuWidget, builder => builder - .Securable() - .Stereotype("Widget") - ); + _contentDefinitionManager.AlterTypeDefinition(MenuWidget, builder => builder + .Securable() + .Stereotype("Widget") + ); - return 3; - } + return 3; + } - public int UpdateFrom1() - { - _contentDefinitionManager.AlterTypeDefinition(ContainerWidget, builder => builder - .WithPart("TitlePart", part => part.WithPosition("0")) - .WithPart("FlowPart", part => part.WithPosition("1")) - ); + public int UpdateFrom1() + { + _contentDefinitionManager.AlterTypeDefinition(ContainerWidget, builder => builder + .WithPart("TitlePart", part => part.WithPosition("0")) + .WithPart("FlowPart", part => part.WithPosition("1")) + ); - return 2; - } + return 2; + } - public int UpdateFrom2() - { - _contentDefinitionManager.AlterTypeDefinition(MenuWidget, builder => builder - .Securable() - .Stereotype("Widget") - ); + public int UpdateFrom2() + { + _contentDefinitionManager.AlterTypeDefinition(MenuWidget, builder => builder + .Securable() + .Stereotype("Widget") + ); - return 3; - } + return 3; } } diff --git a/Extensions/Widgets/Startup.cs b/Extensions/Widgets/Startup.cs index 2d1d8437..7e58a1b8 100644 --- a/Extensions/Widgets/Startup.cs +++ b/Extensions/Widgets/Startup.cs @@ -5,17 +5,16 @@ using OrchardCore.Modules; using System; -namespace Lombiq.HelpfulExtensions.Extensions.Widgets +namespace Lombiq.HelpfulExtensions.Extensions.Widgets; + +[Feature(FeatureIds.Widgets)] +public class Startup : StartupBase { - [Feature(FeatureIds.Widgets)] - public class Startup : StartupBase - { - public override void ConfigureServices(IServiceCollection services) => - services.AddScoped(); + public override void ConfigureServices(IServiceCollection services) => + services.AddScoped(); - public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) - { - // No need for anything here yet. - } + public override void Configure(IApplicationBuilder app, IEndpointRouteBuilder routes, IServiceProvider serviceProvider) + { + // No need for anything here yet. } } diff --git a/Extensions/Widgets/ViewModels/MenuWidgetViewModel.cs b/Extensions/Widgets/ViewModels/MenuWidgetViewModel.cs index 2e395c2a..d2197381 100644 --- a/Extensions/Widgets/ViewModels/MenuWidgetViewModel.cs +++ b/Extensions/Widgets/ViewModels/MenuWidgetViewModel.cs @@ -2,22 +2,21 @@ using System.Collections.Generic; using System.Linq; -namespace Lombiq.HelpfulExtensions.Extensions.Widgets.ViewModels +namespace Lombiq.HelpfulExtensions.Extensions.Widgets.ViewModels; + +public class MenuWidgetViewModel { - public class MenuWidgetViewModel - { - public bool NoWrapper { get; set; } - public IEnumerable MenuItems { get; set; } + public bool NoWrapper { get; set; } + public IEnumerable MenuItems { get; set; } - public MenuWidgetViewModel(bool noWrapper = false, IEnumerable menuItems = null) - { - NoWrapper = noWrapper; - MenuItems = menuItems ?? Enumerable.Empty(); - } + public MenuWidgetViewModel(bool noWrapper = false, IEnumerable menuItems = null) + { + NoWrapper = noWrapper; + MenuItems = menuItems ?? Enumerable.Empty(); + } - public MenuWidgetViewModel(dynamic model) - : this((model.NoWrapper as bool?) == true, model.MenuItems as IEnumerable) - { - } + public MenuWidgetViewModel(dynamic model) + : this((model.NoWrapper as bool?) == true, model.MenuItems as IEnumerable) + { } } diff --git a/Extensions/Widgets/WidgetTypes.cs b/Extensions/Widgets/WidgetTypes.cs index 78b63219..6cadee57 100644 --- a/Extensions/Widgets/WidgetTypes.cs +++ b/Extensions/Widgets/WidgetTypes.cs @@ -1,10 +1,9 @@ -namespace Lombiq.HelpfulExtensions.Extensions.Widgets +namespace Lombiq.HelpfulExtensions.Extensions.Widgets; + +public static class WidgetTypes { - public static class WidgetTypes - { - public const string ContainerWidget = nameof(ContainerWidget); - public const string HtmlWidget = nameof(HtmlWidget); - public const string LiquidWidget = nameof(LiquidWidget); - public const string MenuWidget = nameof(MenuWidget); - } + public const string ContainerWidget = nameof(ContainerWidget); + public const string HtmlWidget = nameof(HtmlWidget); + public const string LiquidWidget = nameof(LiquidWidget); + public const string MenuWidget = nameof(MenuWidget); } diff --git a/FeatureIds.cs b/FeatureIds.cs index 75e1a8de..ff1218ce 100644 --- a/FeatureIds.cs +++ b/FeatureIds.cs @@ -1,15 +1,14 @@ -namespace Lombiq.HelpfulExtensions +namespace Lombiq.HelpfulExtensions; + +public static class FeatureIds { - public static class FeatureIds - { - private const string FeatureIdPrefix = "Lombiq.HelpfulExtensions."; + private const string FeatureIdPrefix = "Lombiq.HelpfulExtensions."; - public const string CodeGeneration = FeatureIdPrefix + nameof(CodeGeneration); - public const string ContentTypes = FeatureIdPrefix + nameof(ContentTypes); - public const string Flows = FeatureIdPrefix + nameof(Flows); - public const string ShapeTracing = FeatureIdPrefix + nameof(ShapeTracing); - public const string Widgets = FeatureIdPrefix + nameof(Widgets); - public const string Emails = FeatureIdPrefix + nameof(Emails); - public const string Security = FeatureIdPrefix + nameof(Security); - } + public const string CodeGeneration = FeatureIdPrefix + nameof(CodeGeneration); + public const string ContentTypes = FeatureIdPrefix + nameof(ContentTypes); + public const string Flows = FeatureIdPrefix + nameof(Flows); + public const string ShapeTracing = FeatureIdPrefix + nameof(ShapeTracing); + public const string Widgets = FeatureIdPrefix + nameof(Widgets); + public const string Emails = FeatureIdPrefix + nameof(Emails); + public const string Security = FeatureIdPrefix + nameof(Security); } diff --git a/Lombiq.HelpfulExtensions.csproj b/Lombiq.HelpfulExtensions.csproj index 6e7da8b5..fd951b47 100644 --- a/Lombiq.HelpfulExtensions.csproj +++ b/Lombiq.HelpfulExtensions.csproj @@ -1,7 +1,7 @@ - netcoreapp3.1 + net6.0 true $(DefaultItemExcludes);.git*;node_modules\** @@ -34,12 +34,12 @@ - - - - - - + + + + + + diff --git a/Models/BootstrapAccordionItem.cs b/Models/BootstrapAccordionItem.cs index 83162524..f3924f4a 100644 --- a/Models/BootstrapAccordionItem.cs +++ b/Models/BootstrapAccordionItem.cs @@ -1,11 +1,10 @@ using Microsoft.AspNetCore.Mvc.Localization; using OrchardCore.DisplayManagement; -namespace Lombiq.HelpfulExtensions.Models +namespace Lombiq.HelpfulExtensions.Models; + +public class BootstrapAccordionItem { - public class BootstrapAccordionItem - { - public LocalizedHtmlString Title { get; set; } - public IShape Shape { get; set; } - } + public LocalizedHtmlString Title { get; set; } + public IShape Shape { get; set; } } diff --git a/Views/Layout-EmailTemplate.cshtml b/Views/Layout-EmailTemplate.cshtml index 0c765a97..f21a5736 100644 --- a/Views/Layout-EmailTemplate.cshtml +++ b/Views/Layout-EmailTemplate.cshtml @@ -20,26 +20,25 @@ - - -
-
- @await RenderSectionAsync("Header", required: false) -
- -
- @await RenderSectionAsync("BeforeContent", required: false) - @await RenderBodyAsync() - @await RenderSectionAsync("AfterContent", required: false) + + +
+
+ @await RenderSectionAsync("Header", required: false) +
+ +
+ @await RenderSectionAsync("BeforeContent", required: false) + @await RenderBodyAsync() + @await RenderSectionAsync("AfterContent", required: false) +
+ +
- -
- - - \ No newline at end of file +