From f831af207b6cabb43bebe8f153c010f4210f9115 Mon Sep 17 00:00:00 2001 From: Jacob Overgaard <752371+iOvergaard@users.noreply.github.com> Date: Fri, 29 Apr 2022 09:09:40 +0200 Subject: [PATCH] add basic structure for languages and allowedLanguages --- .../Models/ContentEditing/UserGroupBasic.cs | 4 +++ .../Models/Mapping/UserMapDefinition.cs | 32 ++++++++++++++----- .../Models/Membership/IReadOnlyUserGroup.cs | 2 ++ .../Models/Membership/IUserGroup.cs | 8 +++++ .../Models/Membership/ReadOnlyUserGroup.cs | 4 ++- .../Models/Membership/UserGroup.cs | 24 ++++++++++++++ .../Models/Membership/UserGroupExtensions.cs | 2 +- .../Persistence/Factories/UserFactory.cs | 3 +- 8 files changed, 68 insertions(+), 11 deletions(-) diff --git a/src/Umbraco.Core/Models/ContentEditing/UserGroupBasic.cs b/src/Umbraco.Core/Models/ContentEditing/UserGroupBasic.cs index ffcfde8368..79a8e2aa47 100644 --- a/src/Umbraco.Core/Models/ContentEditing/UserGroupBasic.cs +++ b/src/Umbraco.Core/Models/ContentEditing/UserGroupBasic.cs @@ -10,6 +10,7 @@ namespace Umbraco.Cms.Core.Models.ContentEditing public UserGroupBasic() { Notifications = new List(); + Languages = Enumerable.Empty(); Sections = Enumerable.Empty
(); } @@ -19,6 +20,9 @@ namespace Umbraco.Cms.Core.Models.ContentEditing [DataMember(Name = "notifications")] public List Notifications { get; private set; } + [DataMember(Name = "languages")] + public IEnumerable Languages { get; set; } + [DataMember(Name = "sections")] public IEnumerable
Sections { get; set; } diff --git a/src/Umbraco.Core/Models/Mapping/UserMapDefinition.cs b/src/Umbraco.Core/Models/Mapping/UserMapDefinition.cs index a2c3fa7f28..728ce73a1f 100644 --- a/src/Umbraco.Core/Models/Mapping/UserMapDefinition.cs +++ b/src/Umbraco.Core/Models/Mapping/UserMapDefinition.cs @@ -31,10 +31,11 @@ namespace Umbraco.Cms.Core.Models.Mapping private readonly MediaFileManager _mediaFileManager; private readonly IShortStringHelper _shortStringHelper; private readonly IImageUrlGenerator _imageUrlGenerator; + private readonly ILocalizationService _localizationService; public UserMapDefinition(ILocalizedTextService textService, IUserService userService, IEntityService entityService, ISectionService sectionService, AppCaches appCaches, ActionCollection actions, IOptions globalSettings, MediaFileManager mediaFileManager, IShortStringHelper shortStringHelper, - IImageUrlGenerator imageUrlGenerator) + IImageUrlGenerator imageUrlGenerator, ILocalizationService localizationService) { _sectionService = sectionService; _entityService = entityService; @@ -46,6 +47,7 @@ namespace Umbraco.Cms.Core.Models.Mapping _mediaFileManager = mediaFileManager; _shortStringHelper = shortStringHelper; _imageUrlGenerator = imageUrlGenerator; + _localizationService = localizationService; } public void DefineMaps(IUmbracoMapper mapper) @@ -154,7 +156,7 @@ namespace Umbraco.Cms.Core.Models.Mapping target.UserId = source.Id; } - // Umbraco.Code.MapAll -ContentStartNode -UserCount -MediaStartNode -Key -Sections + // Umbraco.Code.MapAll -ContentStartNode -UserCount -MediaStartNode -Key -Languages -Sections // Umbraco.Code.MapAll -Notifications -Udi -Trashed -AdditionalData -IsSystemUserGroup private void Map(IReadOnlyUserGroup source, UserGroupBasic target, MapperContext context) { @@ -166,10 +168,10 @@ namespace Umbraco.Cms.Core.Models.Mapping target.Path = "-1," + source.Id; target.IsSystemUserGroup = source.IsSystemUserGroup(); - MapUserGroupBasic(target, source.AllowedSections, source.StartContentId, source.StartMediaId, context); + MapUserGroupBasic(target, source.AllowedLanguages, source.AllowedSections, source.StartContentId, source.StartMediaId, context); } - // Umbraco.Code.MapAll -ContentStartNode -MediaStartNode -Sections -Notifications + // Umbraco.Code.MapAll -ContentStartNode -MediaStartNode -Languages -Sections -Notifications // Umbraco.Code.MapAll -Udi -Trashed -AdditionalData -IsSystemUserGroup private void Map(IUserGroup source, UserGroupBasic target, MapperContext context) { @@ -183,7 +185,7 @@ namespace Umbraco.Cms.Core.Models.Mapping target.UserCount = source.UserCount; target.IsSystemUserGroup = source.IsSystemUserGroup(); - MapUserGroupBasic(target, source.AllowedSections, source.StartContentId, source.StartMediaId, context); + MapUserGroupBasic(target, source.AllowedLanguages, source.AllowedSections, source.StartContentId, source.StartMediaId, context); } // Umbraco.Code.MapAll -Udi -Trashed -AdditionalData -AssignedPermissions @@ -218,7 +220,7 @@ namespace Umbraco.Cms.Core.Models.Mapping target.Icon = Constants.Icons.Member; } - // Umbraco.Code.MapAll -ContentStartNode -MediaStartNode -Sections -Notifications -Udi + // Umbraco.Code.MapAll -ContentStartNode -MediaStartNode -Languages -Sections -Notifications -Udi // Umbraco.Code.MapAll -Trashed -AdditionalData -Users -AssignedPermissions private void Map(IUserGroup source, UserGroupDisplay target, MapperContext context) { @@ -233,7 +235,7 @@ namespace Umbraco.Cms.Core.Models.Mapping target.UserCount = source.UserCount; target.IsSystemUserGroup = source.IsSystemUserGroup(); - MapUserGroupBasic(target, source.AllowedSections, source.StartContentId, source.StartMediaId, context); + MapUserGroupBasic(target, source.AllowedLanguages, source.AllowedSections, source.StartContentId, source.StartMediaId, context); //Important! Currently we are never mapping to multiple UserGroupDisplay objects but if we start doing that // this will cause an N+1 and we'll need to change how this works. @@ -360,8 +362,22 @@ namespace Umbraco.Cms.Core.Models.Mapping // helpers - private void MapUserGroupBasic(UserGroupBasic target, IEnumerable sourceAllowedSections, int? sourceStartContentId, int? sourceStartMediaId, MapperContext context) + private void MapUserGroupBasic(UserGroupBasic target, IEnumerable sourceAllowedLanguages, IEnumerable sourceAllowedSections, int? sourceStartContentId, int? sourceStartMediaId, MapperContext context) { + var allLanguages = _localizationService.GetAllLanguages(); + var applicableLanguages = Enumerable.Empty(); + + if (sourceAllowedLanguages.Any()) + { + applicableLanguages = allLanguages.Where(x => sourceAllowedLanguages.Contains(x.Id)); + } + else if (allLanguages.Any()) + { + applicableLanguages = allLanguages; + } + + target.Languages = context.MapEnumerable(applicableLanguages).WhereNotNull(); + var allSections = _sectionService.GetSections(); target.Sections = context.MapEnumerable(allSections.Where(x => sourceAllowedSections.Contains(x.Alias))).WhereNotNull(); diff --git a/src/Umbraco.Core/Models/Membership/IReadOnlyUserGroup.cs b/src/Umbraco.Core/Models/Membership/IReadOnlyUserGroup.cs index be84b4bca6..d916fd4b10 100644 --- a/src/Umbraco.Core/Models/Membership/IReadOnlyUserGroup.cs +++ b/src/Umbraco.Core/Models/Membership/IReadOnlyUserGroup.cs @@ -27,5 +27,7 @@ namespace Umbraco.Cms.Core.Models.Membership IEnumerable? Permissions { get; set; } IEnumerable AllowedSections { get; } + + IEnumerable AllowedLanguages { get; } } } diff --git a/src/Umbraco.Core/Models/Membership/IUserGroup.cs b/src/Umbraco.Core/Models/Membership/IUserGroup.cs index 96ae3c6dfb..e82237da95 100644 --- a/src/Umbraco.Core/Models/Membership/IUserGroup.cs +++ b/src/Umbraco.Core/Models/Membership/IUserGroup.cs @@ -36,6 +36,14 @@ namespace Umbraco.Cms.Core.Models.Membership void ClearAllowedSections(); + IEnumerable AllowedLanguages { get; } + + void RemoveAllowedLanguage(int languageId); + + void AddAllowedLanguage(int languageId); + + void ClearAllowedLanguages(); + /// /// Specifies the number of users assigned to this group /// diff --git a/src/Umbraco.Core/Models/Membership/ReadOnlyUserGroup.cs b/src/Umbraco.Core/Models/Membership/ReadOnlyUserGroup.cs index 24543337ba..e487551b00 100644 --- a/src/Umbraco.Core/Models/Membership/ReadOnlyUserGroup.cs +++ b/src/Umbraco.Core/Models/Membership/ReadOnlyUserGroup.cs @@ -7,12 +7,13 @@ namespace Umbraco.Cms.Core.Models.Membership public class ReadOnlyUserGroup : IReadOnlyUserGroup, IEquatable { public ReadOnlyUserGroup(int id, string? name, string? icon, int? startContentId, int? startMediaId, string? @alias, - IEnumerable allowedSections, IEnumerable? permissions) + IEnumerable allowedLanguages, IEnumerable allowedSections, IEnumerable? permissions) { Name = name ?? string.Empty; Icon = icon; Id = id; Alias = alias ?? string.Empty; + AllowedLanguages = allowedLanguages.ToArray(); AllowedSections = allowedSections.ToArray(); Permissions = permissions?.ToArray(); @@ -35,6 +36,7 @@ namespace Umbraco.Cms.Core.Models.Membership /// By default each permission is simply a single char but we've made this an enumerable{string} to support a more flexible permissions structure in the future. /// public IEnumerable? Permissions { get; set; } + public IEnumerable AllowedLanguages { get; private set; } public IEnumerable AllowedSections { get; private set; } public bool Equals(ReadOnlyUserGroup? other) diff --git a/src/Umbraco.Core/Models/Membership/UserGroup.cs b/src/Umbraco.Core/Models/Membership/UserGroup.cs index 5807a83abe..3e0947a68a 100644 --- a/src/Umbraco.Core/Models/Membership/UserGroup.cs +++ b/src/Umbraco.Core/Models/Membership/UserGroup.cs @@ -22,6 +22,7 @@ namespace Umbraco.Cms.Core.Models.Membership private string _name; private IEnumerable? _permissions; private List _sectionCollection; + private List _languageCollection; //Custom comparer for enumerable private static readonly DelegateEqualityComparer> StringEnumerableComparer = @@ -38,6 +39,7 @@ namespace Umbraco.Cms.Core.Models.Membership _name = string.Empty; _shortStringHelper = shortStringHelper; _sectionCollection = new List(); + _languageCollection = new List(); } /// @@ -128,6 +130,28 @@ namespace Umbraco.Cms.Core.Models.Membership _sectionCollection.Clear(); } + public IEnumerable AllowedLanguages + { + get => _languageCollection; + } + + public void RemoveAllowedLanguage(int languageId) + { + if (_languageCollection.Contains(languageId)) + _languageCollection.Remove(languageId); + } + + public void AddAllowedLanguage(int languageId) + { + if (_languageCollection.Contains(languageId) == false) + _languageCollection.Add(languageId); + } + + public void ClearAllowedLanguages() + { + _languageCollection.Clear(); + } + public int UserCount { get; } protected override void PerformDeepClone(object clone) diff --git a/src/Umbraco.Core/Models/Membership/UserGroupExtensions.cs b/src/Umbraco.Core/Models/Membership/UserGroupExtensions.cs index 84b165b81e..95c4d9f0dd 100644 --- a/src/Umbraco.Core/Models/Membership/UserGroupExtensions.cs +++ b/src/Umbraco.Core/Models/Membership/UserGroupExtensions.cs @@ -12,7 +12,7 @@ namespace Umbraco.Extensions if (readonlyGroup != null) return readonlyGroup; //otherwise create one - return new ReadOnlyUserGroup(group.Id, group.Name, group.Icon, group.StartContentId, group.StartMediaId, group.Alias, group.AllowedSections, group.Permissions); + return new ReadOnlyUserGroup(group.Id, group.Name, group.Icon, group.StartContentId, group.StartMediaId, group.Alias, group.AllowedLanguages, group.AllowedSections, group.Permissions); } public static bool IsSystemUserGroup(this IUserGroup group) => diff --git a/src/Umbraco.Infrastructure/Persistence/Factories/UserFactory.cs b/src/Umbraco.Infrastructure/Persistence/Factories/UserFactory.cs index 8ee2bcfec0..1e548fdc30 100644 --- a/src/Umbraco.Infrastructure/Persistence/Factories/UserFactory.cs +++ b/src/Umbraco.Infrastructure/Persistence/Factories/UserFactory.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Linq; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Models.Membership; @@ -112,6 +112,7 @@ namespace Umbraco.Cms.Infrastructure.Persistence.Factories { return new ReadOnlyUserGroup(group.Id, group.Name, group.Icon, group.StartContentId, group.StartMediaId, group.Alias, + Enumerable.Empty(), // TODO: Need to find the real languages when the dto model is updated group.UserGroup2AppDtos.Select(x => x.AppAlias).WhereNotNull().ToArray(), group.DefaultPermissions == null ? Enumerable.Empty() : group.DefaultPermissions.ToCharArray().Select(x => x.ToString())); }