From 01f4acd37c5c405381daf61249a35fa18e395d8a Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Tue, 25 Oct 2022 14:58:19 +0200 Subject: [PATCH 1/6] Allow for configuration of additional languages to install and ensure one is set as default. --- .../Migrations/Install/DatabaseDataCreator.cs | 48 ++++++++++++++++--- 1 file changed, 41 insertions(+), 7 deletions(-) diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs index 1b01a3ba47d3..b07d574944a7 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs @@ -1,3 +1,4 @@ +using System.Globalization; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using NPoco; @@ -1745,14 +1746,46 @@ private void CreatePropertyTypeData() } } - private void CreateLanguageData() => - ConditionalInsert( + private void CreateLanguageData() + { + var defaultCulture = CultureInfo.GetCultureInfo("en-US"); + bool createdDefaultLanguage = ConditionalInsert( Constants.Configuration.NamedOptions.InstallDefaultData.Languages, "en-us", - new LanguageDto { Id = 1, IsoCode = "en-US", CultureName = "English (United States)", IsDefault = true }, + new LanguageDto { Id = 1, IsoCode = defaultCulture.Name, CultureName = defaultCulture.EnglishName, IsDefault = true }, Constants.DatabaseSchema.Tables.Language, "id"); + // For languages we support the installation of records that are additional to the default installed data. + // We can do this as they are specified by ISO code, which is enough to fully detail them. All other customizable install data is + // specified by GUID, and hence we only know about the set that are installed by default). + InstallDefaultDataSettings? languageInstallDefaultDataSettings = _installDefaultDataSettings.Get(Constants.Configuration.NamedOptions.InstallDefaultData.Languages); + if (languageInstallDefaultDataSettings?.InstallData == InstallDefaultDataOption.Values) + { + CreateSpecifiedlLanguageData(languageInstallDefaultDataSettings.Values, createdDefaultLanguage, defaultCulture.Name); + } + } + + private void CreateSpecifiedlLanguageData(IList isoCodes, bool createdDefaultLanguage, string defaultIsoCode) + { + // Create language records for all specified languages. + // We omit en-US if specified, as that will have been created as the "default default" language already. + // We set the first provided language as the default if we haven't already created one. + var isFirstConfiguredLanguage = true; + foreach (var isoCode in isoCodes.Where(x => !string.Equals(x, defaultIsoCode, StringComparison.OrdinalIgnoreCase))) + { + var culture = new CultureInfo(isoCode); + var dto = new LanguageDto + { + IsoCode = culture.Name, + CultureName = culture.DisplayName, + IsDefault = !createdDefaultLanguage && isFirstConfiguredLanguage + }; + _database.Insert(Constants.DatabaseSchema.Tables.Language, "id", true, dto); + isFirstConfiguredLanguage = false; + } + } + private void CreateContentChildTypeData() { // Insert data if the corresponding Node records exist (which may or may not have been created depending on configuration @@ -2245,7 +2278,7 @@ private void CreateLogViewerQueryData() } } - private void ConditionalInsert( + private bool ConditionalInsert( string configKey, string id, TDto dto, @@ -2266,21 +2299,22 @@ private void ConditionalInsert( if (!alwaysInsert && installDefaultDataSettings?.InstallData == InstallDefaultDataOption.None) { - return; + return false; } if (!alwaysInsert && installDefaultDataSettings?.InstallData == InstallDefaultDataOption.Values && !installDefaultDataSettings.Values.InvariantContains(id)) { - return; + return false; } if (!alwaysInsert && installDefaultDataSettings?.InstallData == InstallDefaultDataOption.ExceptValues && installDefaultDataSettings.Values.InvariantContains(id)) { - return; + return false; } _database.Insert(tableName, primaryKeyName, autoIncrement, dto); + return true; } } From 73548d25b98fa660a6fdbfef838c14db50ef484d Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Wed, 26 Oct 2022 06:49:20 +0200 Subject: [PATCH 2/6] Amended install default language method to handle invalid ISO codes and ensure the first specified language is always made the default. --- .../Migrations/Install/DatabaseDataCreator.cs | 60 +++++++++++++++++++ 1 file changed, 60 insertions(+) diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs index b07d574944a7..c9acb10a9d58 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs @@ -1,4 +1,6 @@ +using System.Diagnostics.CodeAnalysis; using System.Globalization; +using System.Text.RegularExpressions; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using NPoco; @@ -1747,6 +1749,64 @@ private void CreatePropertyTypeData() } private void CreateLanguageData() + { + // For languages we support the installation of records that are additional to the default installed data. + // We can do this as they are specified by ISO code, which is enough to fully detail them. + // All other customizable install data is specified by GUID, and hence we only know about the set that are installed by default. + InstallDefaultDataSettings? languageInstallDefaultDataSettings = _installDefaultDataSettings.Get(Constants.Configuration.NamedOptions.InstallDefaultData.Languages); + if (languageInstallDefaultDataSettings?.InstallData == InstallDefaultDataOption.Values) + { + // Insert the specified languages, ensuring the first is marked as default. + bool isDefault = true; + foreach (var isoCode in languageInstallDefaultDataSettings.Values) + { + if (!TryCreateCulture(isoCode, out CultureInfo? culture)) + { + continue; + } + + var dto = new LanguageDto + { + IsoCode = culture.Name, + CultureName = culture.DisplayName, + IsDefault = isDefault + }; + _database.Insert(Constants.DatabaseSchema.Tables.Language, "id", true, dto); + isDefault = false; + } + } + else + { + // Conditionally insert the default language. + string isoCode = "en-US"; + if (TryCreateCulture(isoCode, out CultureInfo? culture)) + { + ConditionalInsert( + Constants.Configuration.NamedOptions.InstallDefaultData.Languages, + culture.Name, + new LanguageDto { Id = 1, IsoCode = culture.Name, CultureName = culture.EnglishName, IsDefault = true }, + Constants.DatabaseSchema.Tables.Language, + "id"); + } + } + } + + private bool TryCreateCulture(string isoCode, [NotNullWhen(true)] out CultureInfo? culture) + { + try + { + culture = CultureInfo.GetCultureInfo(isoCode); + return true; + } + catch (CultureNotFoundException ex) + { + _logger.LogWarning(ex, "CultureInfo could not be created because culture '{IsoCode}' is not available. The language will not be created.", isoCode); + culture = null; + return false; + } + } + + private void CreateLanguageDataOld() { var defaultCulture = CultureInfo.GetCultureInfo("en-US"); bool createdDefaultLanguage = ConditionalInsert( From f6709bd83c4678a9deafe1b8aecb3166c9a3b362 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Wed, 26 Oct 2022 06:50:57 +0200 Subject: [PATCH 3/6] Removed unnecessary using. --- .../Migrations/Install/DatabaseDataCreator.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs index c9acb10a9d58..3206e53ee960 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs @@ -1,6 +1,5 @@ using System.Diagnostics.CodeAnalysis; using System.Globalization; -using System.Text.RegularExpressions; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Options; using NPoco; From 96f96e3dcf8f5094723dfa3200eb1e5c0c37bd18 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Wed, 26 Oct 2022 12:29:33 +0200 Subject: [PATCH 4/6] Apply suggestions from code review Co-authored-by: Ronald Barendse --- .../Migrations/Install/DatabaseDataCreator.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs index 3206e53ee960..bb565e83a2fa 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs @@ -1767,7 +1767,7 @@ private void CreateLanguageData() var dto = new LanguageDto { IsoCode = culture.Name, - CultureName = culture.DisplayName, + CultureName = culture.EnglishName, IsDefault = isDefault }; _database.Insert(Constants.DatabaseSchema.Tables.Language, "id", true, dto); @@ -1777,8 +1777,7 @@ private void CreateLanguageData() else { // Conditionally insert the default language. - string isoCode = "en-US"; - if (TryCreateCulture(isoCode, out CultureInfo? culture)) + if (TryCreateCulture("en-US", out CultureInfo? culture)) { ConditionalInsert( Constants.Configuration.NamedOptions.InstallDefaultData.Languages, From 829769e8ff99239afc326a376dd4895590ccd3b2 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Wed, 26 Oct 2022 12:35:36 +0200 Subject: [PATCH 5/6] Clean up. --- .../Migrations/Install/DatabaseDataCreator.cs | 49 ++----------------- 1 file changed, 4 insertions(+), 45 deletions(-) diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs index 3206e53ee960..a1aa3d282c71 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs @@ -1805,46 +1805,6 @@ private bool TryCreateCulture(string isoCode, [NotNullWhen(true)] out CultureInf } } - private void CreateLanguageDataOld() - { - var defaultCulture = CultureInfo.GetCultureInfo("en-US"); - bool createdDefaultLanguage = ConditionalInsert( - Constants.Configuration.NamedOptions.InstallDefaultData.Languages, - "en-us", - new LanguageDto { Id = 1, IsoCode = defaultCulture.Name, CultureName = defaultCulture.EnglishName, IsDefault = true }, - Constants.DatabaseSchema.Tables.Language, - "id"); - - // For languages we support the installation of records that are additional to the default installed data. - // We can do this as they are specified by ISO code, which is enough to fully detail them. All other customizable install data is - // specified by GUID, and hence we only know about the set that are installed by default). - InstallDefaultDataSettings? languageInstallDefaultDataSettings = _installDefaultDataSettings.Get(Constants.Configuration.NamedOptions.InstallDefaultData.Languages); - if (languageInstallDefaultDataSettings?.InstallData == InstallDefaultDataOption.Values) - { - CreateSpecifiedlLanguageData(languageInstallDefaultDataSettings.Values, createdDefaultLanguage, defaultCulture.Name); - } - } - - private void CreateSpecifiedlLanguageData(IList isoCodes, bool createdDefaultLanguage, string defaultIsoCode) - { - // Create language records for all specified languages. - // We omit en-US if specified, as that will have been created as the "default default" language already. - // We set the first provided language as the default if we haven't already created one. - var isFirstConfiguredLanguage = true; - foreach (var isoCode in isoCodes.Where(x => !string.Equals(x, defaultIsoCode, StringComparison.OrdinalIgnoreCase))) - { - var culture = new CultureInfo(isoCode); - var dto = new LanguageDto - { - IsoCode = culture.Name, - CultureName = culture.DisplayName, - IsDefault = !createdDefaultLanguage && isFirstConfiguredLanguage - }; - _database.Insert(Constants.DatabaseSchema.Tables.Language, "id", true, dto); - isFirstConfiguredLanguage = false; - } - } - private void CreateContentChildTypeData() { // Insert data if the corresponding Node records exist (which may or may not have been created depending on configuration @@ -2337,7 +2297,7 @@ private void CreateLogViewerQueryData() } } - private bool ConditionalInsert( + private void ConditionalInsert( string configKey, string id, TDto dto, @@ -2358,22 +2318,21 @@ private bool ConditionalInsert( if (!alwaysInsert && installDefaultDataSettings?.InstallData == InstallDefaultDataOption.None) { - return false; + return; } if (!alwaysInsert && installDefaultDataSettings?.InstallData == InstallDefaultDataOption.Values && !installDefaultDataSettings.Values.InvariantContains(id)) { - return false; + return; } if (!alwaysInsert && installDefaultDataSettings?.InstallData == InstallDefaultDataOption.ExceptValues && installDefaultDataSettings.Values.InvariantContains(id)) { - return false; + return; } _database.Insert(tableName, primaryKeyName, autoIncrement, dto); - return true; } } From 05dff9ae86a74ca76595b8d33339b94c02babb73 Mon Sep 17 00:00:00 2001 From: Andy Butland Date: Thu, 27 Oct 2022 14:42:26 +0200 Subject: [PATCH 6/6] Update src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> --- .../Migrations/Install/DatabaseDataCreator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs index 51a7e423ce9d..cc2e20fa0276 100644 --- a/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs +++ b/src/Umbraco.Infrastructure/Migrations/Install/DatabaseDataCreator.cs @@ -1768,7 +1768,7 @@ private void CreateLanguageData() { IsoCode = culture.Name, CultureName = culture.EnglishName, - IsDefault = isDefault + IsDefault = isDefault, }; _database.Insert(Constants.DatabaseSchema.Tables.Language, "id", true, dto); isDefault = false;