diff --git a/src/Umbraco.Core/Models/Membership/IUserGroup.cs b/src/Umbraco.Core/Models/Membership/IUserGroup.cs
index 106f52f569..5e1bc0c4cc 100644
--- a/src/Umbraco.Core/Models/Membership/IUserGroup.cs
+++ b/src/Umbraco.Core/Models/Membership/IUserGroup.cs
@@ -35,5 +35,10 @@ namespace Umbraco.Core.Models.Membership
void AddAllowedSection(string sectionAlias);
void ClearAllowedSections();
+
+ ///
+ /// Specifies the number of users assigned to this group
+ ///
+ int UserCount { get; }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Models/Membership/UserGroup.cs b/src/Umbraco.Core/Models/Membership/UserGroup.cs
index d6674b579d..fff7fac5ea 100644
--- a/src/Umbraco.Core/Models/Membership/UserGroup.cs
+++ b/src/Umbraco.Core/Models/Membership/UserGroup.cs
@@ -39,12 +39,33 @@ namespace Umbraco.Core.Models.Membership
(enum1, enum2) => enum1.UnsortedSequenceEqual(enum2),
enum1 => enum1.GetHashCode());
}
-
+
+ ///
+ /// Constructor to create a new user group
+ ///
public UserGroup()
{
_sectionCollection = new List();
}
+ ///
+ /// Constructor to create an existing user group
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public UserGroup(int userCount, string alias, string name, IEnumerable permissions, string icon)
+ : this()
+ {
+ UserCount = userCount;
+ _alias = alias;
+ _name = name;
+ _permissions = permissions;
+ _icon = icon;
+ }
+
[DataMember]
public int StartMediaId
{
@@ -128,5 +149,7 @@ namespace Umbraco.Core.Models.Membership
{
_sectionCollection.Clear();
}
+
+ public int UserCount { get; private set; }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Models/Rdbms/UserGroupDto.cs b/src/Umbraco.Core/Models/Rdbms/UserGroupDto.cs
index 42df2fcf1c..88071dec02 100644
--- a/src/Umbraco.Core/Models/Rdbms/UserGroupDto.cs
+++ b/src/Umbraco.Core/Models/Rdbms/UserGroupDto.cs
@@ -59,5 +59,11 @@ namespace Umbraco.Core.Models.Rdbms
[ResultColumn]
public List UserGroup2AppDtos { get; set; }
+
+ ///
+ /// This is only relevant when this column is included in the results (i.e. GetUserGroupsWithUserCounts)
+ ///
+ [ResultColumn]
+ public int UserCount { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Factories/UserGroupFactory.cs b/src/Umbraco.Core/Persistence/Factories/UserGroupFactory.cs
index a9cbf95c77..79f03b9910 100644
--- a/src/Umbraco.Core/Persistence/Factories/UserGroupFactory.cs
+++ b/src/Umbraco.Core/Persistence/Factories/UserGroupFactory.cs
@@ -10,22 +10,18 @@ namespace Umbraco.Core.Persistence.Factories
{
public static IUserGroup BuildEntity(UserGroupDto dto)
{
- var userGroup = new UserGroup();
+ var userGroup = new UserGroup(dto.UserCount, dto.Alias, dto.Name,
+ dto.DefaultPermissions.IsNullOrWhiteSpace()
+ ? Enumerable.Empty()
+ : dto.DefaultPermissions.ToCharArray().Select(x => x.ToString(CultureInfo.InvariantCulture)),
+ dto.Icon);
try
{
userGroup.DisableChangeTracking();
-
- userGroup.Alias = dto.Alias;
- userGroup.Id = dto.Id;
- userGroup.Name = dto.Name;
- userGroup.Permissions = dto.DefaultPermissions.IsNullOrWhiteSpace()
- ? Enumerable.Empty()
- : dto.DefaultPermissions.ToCharArray().Select(x => x.ToString(CultureInfo.InvariantCulture));
+ userGroup.Id = dto.Id;
userGroup.CreateDate = dto.CreateDate;
- userGroup.UpdateDate = dto.UpdateDate;
- userGroup.Icon = dto.Icon;
-
+ userGroup.UpdateDate = dto.UpdateDate;
if (dto.UserGroup2AppDtos != null)
{
foreach (var app in dto.UserGroup2AppDtos)
diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserGroupRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserGroupRepository.cs
index 3aca34c5bd..3b2663e026 100644
--- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserGroupRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserGroupRepository.cs
@@ -47,5 +47,6 @@ namespace Umbraco.Core.Persistence.Repositories
/// Permissions as enumerable list of
/// Specify the nodes to replace permissions for
void AssignGroupPermission(int groupId, char permission, params int[] entityIds);
+
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Core/Persistence/Repositories/UserGroupRepository.cs b/src/Umbraco.Core/Persistence/Repositories/UserGroupRepository.cs
index 727f75f96e..4097751534 100644
--- a/src/Umbraco.Core/Persistence/Repositories/UserGroupRepository.cs
+++ b/src/Umbraco.Core/Persistence/Repositories/UserGroupRepository.cs
@@ -77,6 +77,7 @@ namespace Umbraco.Core.Persistence.Repositories
var innerSql = GetBaseQuery("umbracoUserGroup.id");
innerSql.Where("umbracoUserGroup2App.app = " + SqlSyntax.GetQuotedValue(sectionAlias));
sql.Where(string.Format("umbracoUserGroup.id IN ({0})", innerSql.SQL));
+ AppendGroupBy(sql);
//must be included for relator to work
sql.OrderBy(x => x.Id, SqlSyntax);
@@ -122,7 +123,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
var repo = new PermissionRepository(UnitOfWork, _cacheHelper, SqlSyntax);
repo.AssignPermission(groupId, permission, entityIds);
- }
+ }
#region Overrides of RepositoryBase
@@ -130,6 +131,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
var sql = GetBaseQuery(false);
sql.Where(GetBaseWhereClause(), new { Id = id });
+ AppendGroupBy(sql);
//must be included for relator to work
sql.OrderBy(x => x.Id, SqlSyntax);
@@ -154,6 +156,7 @@ namespace Umbraco.Core.Persistence.Repositories
{
sql.Where(x => x.Id >= 0);
}
+ AppendGroupBy(sql);
//must be included for relator to work
sql.OrderBy(x => x.Id, SqlSyntax);
@@ -166,6 +169,7 @@ namespace Umbraco.Core.Persistence.Repositories
var sqlClause = GetBaseQuery(false);
var translator = new SqlTranslator(sqlClause, query);
var sql = translator.Translate();
+ AppendGroupBy(sql);
//must be included for relator to work
sql.OrderBy(x => x.Id, SqlSyntax);
@@ -186,7 +190,7 @@ namespace Umbraco.Core.Persistence.Repositories
}
else
{
- return GetBaseQuery("*");
+ return GetBaseQuery("umbracoUserGroup.*, COUNT(umbracoUser.id) AS UserCount, umbracoUserGroup2App.*");
}
return sql;
}
@@ -197,11 +201,22 @@ namespace Umbraco.Core.Persistence.Repositories
sql.Select(columns)
.From()
.LeftJoin()
- .On(left => left.Id, right => right.UserGroupId);
+ .On(left => left.Id, right => right.UserGroupId)
+ .LeftJoin()
+ .On(left => left.UserGroupId, right => right.Id)
+ .LeftJoin()
+ .On(left => left.Id, right => right.UserId);
return sql;
}
+ private void AppendGroupBy(Sql sql)
+ {
+ sql.GroupBy(@"umbracoUserGroup.createDate, umbracoUserGroup.icon, umbracoUserGroup.id, umbracoUserGroup.startContentId,
+umbracoUserGroup.startMediaId, umbracoUserGroup.updateDate, umbracoUserGroup.userGroupAlias, umbracoUserGroup.userGroupDefaultPermissions,
+umbracoUserGroup.userGroupName, umbracoUserGroup2App.app, umbracoUserGroup2App.userGroupId");
+ }
+
protected override string GetBaseWhereClause()
{
return "umbracoUserGroup.id = @Id";
diff --git a/src/Umbraco.Core/Services/IUserService.cs b/src/Umbraco.Core/Services/IUserService.cs
index 3903cc5096..162ee4fb85 100644
--- a/src/Umbraco.Core/Services/IUserService.cs
+++ b/src/Umbraco.Core/Services/IUserService.cs
@@ -182,7 +182,7 @@ namespace Umbraco.Core.Services
///
IEnumerable GetAllNotInGroup(int groupId);
- #region User groups
+ #region User groups
///
/// Gets all UserGroups or those specified as parameters
diff --git a/src/Umbraco.Core/Services/UserService.cs b/src/Umbraco.Core/Services/UserService.cs
index 99b4b56cdd..e4eed2ce04 100644
--- a/src/Umbraco.Core/Services/UserService.cs
+++ b/src/Umbraco.Core/Services/UserService.cs
@@ -601,7 +601,7 @@ namespace Umbraco.Core.Services
{
return repository.GetAllNotInGroup(groupId);
}
- }
+ }
#endregion
diff --git a/src/Umbraco.Web/Models/ContentEditing/UserGroupBasic.cs b/src/Umbraco.Web/Models/ContentEditing/UserGroupBasic.cs
index 3d6b304bef..d34ec6cf67 100644
--- a/src/Umbraco.Web/Models/ContentEditing/UserGroupBasic.cs
+++ b/src/Umbraco.Web/Models/ContentEditing/UserGroupBasic.cs
@@ -25,5 +25,11 @@ namespace Umbraco.Web.Models.ContentEditing
[DataMember(Name = "startMediaId")]
public EntityBasic StartMediaId { get; set; }
+
+ ///
+ /// The number of users assigned to this group
+ ///
+ [DataMember(Name = "userCount")]
+ public int UserCount { get; set; }
}
}
\ No newline at end of file
diff --git a/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs b/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs
index e5baa81fac..f5139460ff 100644
--- a/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs
+++ b/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs
@@ -52,6 +52,7 @@ namespace Umbraco.Web.Models.Mapping
config.CreateMap()
.ForMember(detail => detail.StartContentId, opt => opt.Ignore())
+ .ForMember(detail => detail.UserCount, opt => opt.Ignore())
.ForMember(detail => detail.StartMediaId, opt => opt.Ignore())
.ForMember(detail => detail.Key, opt => opt.Ignore())
.ForMember(detail => detail.Sections, opt => opt.Ignore())