From c5945789f061325ce64fef2385aa2dabf1bab256 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Tue, 3 Sep 2013 17:02:15 +0200 Subject: [PATCH] Refactoring the MemberRepository to use the new Member class --- src/Umbraco.Core/Models/IMember.cs | 111 ++++++++++- src/Umbraco.Core/Models/MemberType.cs | 2 +- .../Persistence/Factories/MemberFactory.cs | 2 +- .../Factories/MemberReadOnlyFactory.cs | 185 +++--------------- .../Persistence/Mappers/MappingResolver.cs | 2 - .../Persistence/Mappers/MemberMapper.cs | 3 +- .../Persistence/Mappers/MemberTypeMapper.cs | 2 +- .../Interfaces/IMemberRepository.cs | 2 +- .../Repositories/MemberRepository.cs | 31 ++- .../Persistence/RepositoryFactory.cs | 2 +- 10 files changed, 172 insertions(+), 170 deletions(-) diff --git a/src/Umbraco.Core/Models/IMember.cs b/src/Umbraco.Core/Models/IMember.cs index 226e3dc70d..0b347a2515 100644 --- a/src/Umbraco.Core/Models/IMember.cs +++ b/src/Umbraco.Core/Models/IMember.cs @@ -1,7 +1,114 @@ -namespace Umbraco.Core.Models +using System; + +namespace Umbraco.Core.Models { public interface IMember : IContentBase { - + /// + /// Gets or sets the Username + /// + string Username { get; set; } + + /// + /// Gets or sets the Email + /// + string Email { get; set; } + + /// + /// Gets or sets the Password + /// + string Password { get; set; } + + /// + /// Gets or sets the Password Question + /// + /// + /// Alias: umbracoPasswordRetrievalQuestionPropertyTypeAlias + /// Part of the standard properties collection. + /// + string PasswordQuestion { get; set; } + + /// + /// Gets or sets the Password Answer + /// + /// + /// Alias: umbracoPasswordRetrievalAnswerPropertyTypeAlias + /// Part of the standard properties collection. + /// + string PasswordAnswer { get; set; } + + /// + /// Gets or set the comments for the member + /// + /// + /// Alias: umbracoCommentPropertyTypeAlias + /// Part of the standard properties collection. + /// + string Comments { get; set; } + + /// + /// Gets or sets a boolean indicating whether the Member is approved + /// + /// + /// Alias: umbracoApprovePropertyTypeAlias + /// Part of the standard properties collection. + /// + bool IsApproved { get; set; } + + /// + /// Gets or sets a boolean indicating whether the Member is locked out + /// + /// + /// Alias: umbracoLockPropertyTypeAlias + /// Part of the standard properties collection. + /// + bool IsLockedOut { get; set; } + + /// + /// Gets or sets the date for last login + /// + /// + /// Alias: umbracoLastLoginPropertyTypeAlias + /// Part of the standard properties collection. + /// + DateTime LastLoginDate { get; set; } + + /// + /// Gest or sets the date for last password change + /// + /// + /// Alias: umbracoMemberLastPasswordChange + /// Part of the standard properties collection. + /// + DateTime LastPasswordChangeDate { get; set; } + + /// + /// Gets or sets the date for when Member was locked out + /// + /// + /// Alias: umbracoMemberLastLockout + /// Part of the standard properties collection. + /// + DateTime LastLockoutDate { get; set; } + + /// + /// Gets or sets the number of failed password attempts. + /// This is the number of times the password was entered incorrectly upon login. + /// + /// + /// Alias: umbracoFailedPasswordAttemptsPropertyTypeAlias + /// Part of the standard properties collection. + /// + int FailedPasswordAttempts { get; set; } + + /// + /// String alias of the default ContentType + /// + string ContentTypeAlias { get; } + + /// + /// Gets the ContentType used by this content object + /// + IMemberType ContentType { get; } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/MemberType.cs b/src/Umbraco.Core/Models/MemberType.cs index 834f783e09..ed7d5cd3ab 100644 --- a/src/Umbraco.Core/Models/MemberType.cs +++ b/src/Umbraco.Core/Models/MemberType.cs @@ -26,7 +26,7 @@ namespace Umbraco.Core.Models _memberTypePropertyTypes = new Dictionary>(); } - private static readonly PropertyInfo MemberTypePropertyTypesSelector = ExpressionHelper.GetPropertyInfo>>(x => x.MemberTypePropertyTypes); + private static readonly PropertyInfo MemberTypePropertyTypesSelector = ExpressionHelper.GetPropertyInfo>>(x => x.MemberTypePropertyTypes); /// /// Gets or Sets a Dictionary of Tuples (MemberCanEdit, VisibleOnProfile, PropertyTypeId) by the PropertyTypes' alias. diff --git a/src/Umbraco.Core/Persistence/Factories/MemberFactory.cs b/src/Umbraco.Core/Persistence/Factories/MemberFactory.cs index b22a074bca..1aa8f70bb8 100644 --- a/src/Umbraco.Core/Persistence/Factories/MemberFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/MemberFactory.cs @@ -1,7 +1,7 @@ using System; using System.Globalization; using Umbraco.Core.Models.EntityBase; -using Umbraco.Core.Models.Membership; +using Umbraco.Core.Models; using Umbraco.Core.Models.Rdbms; namespace Umbraco.Core.Persistence.Factories diff --git a/src/Umbraco.Core/Persistence/Factories/MemberReadOnlyFactory.cs b/src/Umbraco.Core/Persistence/Factories/MemberReadOnlyFactory.cs index 5e1a8a8147..eb6e2c787d 100644 --- a/src/Umbraco.Core/Persistence/Factories/MemberReadOnlyFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/MemberReadOnlyFactory.cs @@ -1,19 +1,26 @@ using System; -using System.Linq; using System.Collections.Generic; +using System.Linq; using Umbraco.Core.Models; -using Umbraco.Core.Models.EntityBase; -using Umbraco.Core.Models.Membership; using Umbraco.Core.Models.Rdbms; -using IMember = Umbraco.Core.Models.Membership.IMember; namespace Umbraco.Core.Persistence.Factories { internal class MemberReadOnlyFactory : IEntityFactory { + private readonly IDictionary _memberTypes; + + public MemberReadOnlyFactory(IDictionary memberTypes) + { + _memberTypes = memberTypes; + } + public IMember BuildEntity(MemberReadOnlyDto dto) { - var member = new Umbraco.Core.Models.Membership.Member() + var properties = CreateProperties(_memberTypes[dto.ContentTypeAlias], dto.Properties, dto.CreateDate); + var propertyCollection = new PropertyCollection(properties); + + var member = new Member(dto.Text, dto.ParentId, _memberTypes[dto.ContentTypeAlias], propertyCollection) { Id = dto.NodeId, CreateDate = dto.CreateDate, @@ -25,34 +32,14 @@ namespace Umbraco.Core.Persistence.Factories ProviderUserKey = dto.UniqueId, Trashed = dto.Trashed, Key = dto.UniqueId.Value, - ProfileId = dto.UniqueId.Value, - ContentTypeId = dto.ContentTypeId, + CreatorId = dto.UserId.HasValue ? dto.UserId.Value : 0, + Level = dto.Level, + Path = dto.Path, + SortOrder = dto.SortOrder, + Version = dto.VersionId, ContentTypeAlias = dto.ContentTypeAlias }; - ((IUmbracoEntity)member).CreatorId = dto.UserId.Value; - ((IUmbracoEntity)member).Level = dto.Level; - ((IUmbracoEntity)member).ParentId = dto.ParentId; - ((IUmbracoEntity)member).Path = dto.Path; - ((IUmbracoEntity)member).SortOrder = dto.SortOrder; - - var propertyTypes = GetStandardPropertyTypeStubs(); - var propertiesDictionary = dto.Properties.ToDictionary(x => x.Alias); - foreach (var property in propertiesDictionary) - { - if (propertyTypes.ContainsKey(property.Key)) - { - UpdatePropertyType(propertyTypes[property.Key], property.Value); - } - else - { - propertyTypes.Add(property.Key, CreateProperty(property.Value)); - } - } - - var properties = CreateProperties(propertyTypes, propertiesDictionary); - member.Properties = new PropertyCollection(properties); - member.SetProviderUserKeyType(typeof(Guid)); member.ResetDirtyProperties(false); return member; @@ -63,135 +50,27 @@ namespace Umbraco.Core.Persistence.Factories throw new System.NotImplementedException(); } - private IEnumerable CreateProperties(Dictionary propertyTypes, Dictionary propertiesDictionary) + public IEnumerable CreateProperties(IMemberType memberType, IEnumerable dtos, DateTime createDate) { var properties = new List(); - foreach (var propertyType in propertyTypes) + + foreach (var propertyType in memberType.CompositionPropertyTypes) { - if (propertiesDictionary.ContainsKey(propertyType.Key)) - { - var prop = propertiesDictionary[propertyType.Key]; - if (prop.PropertyDataId.HasValue && prop.PropertyDataId.Value != default(int)) - { - properties.Add(propertyType.Value.CreatePropertyFromRawValue(prop.GetValue, prop.VersionId, prop.PropertyDataId.Value)); - } - else - { - properties.Add(propertyType.Value.CreatePropertyFromValue(prop.GetValue)); - } - } - else - { - properties.Add(propertyType.Value.CreatePropertyFromValue(null)); - } + var propertyDataDto = dtos.LastOrDefault(x => x.PropertyTypeId == propertyType.Id); + var property = propertyDataDto == null + ? propertyType.CreatePropertyFromValue(null) + : propertyType.CreatePropertyFromRawValue(propertyDataDto.GetValue, + propertyDataDto.VersionId, + propertyDataDto.Id); + //on initial construction we don't want to have dirty properties tracked + property.CreateDate = createDate; + property.UpdateDate = createDate; + // http://issues.umbraco.org/issue/U4-1946 + property.ResetDirtyProperties(false); + properties.Add(property); } return properties; } - - private PropertyType CreateProperty(PropertyDataReadOnlyDto property) - { - var propertyType = new PropertyType(property.ControlId, property.DbType.EnumParse(true)) - { - Id = property.Id, - Alias = property.Alias, - Name = property.Name, - Description = property.Description, - HelpText = property.HelpText, - Mandatory = property.Mandatory, - ValidationRegExp = property.ValidationRegExp, - SortOrder = property.SortOrder - }; - - if(property.PropertyTypeGroupId.HasValue) - propertyType.PropertyGroupId = new Lazy(() => property.PropertyTypeGroupId.Value); - - return propertyType; - } - - private void UpdatePropertyType(PropertyType propertyType, PropertyDataReadOnlyDto property) - { - propertyType.Id = property.Id; - propertyType.Alias = property.Alias; - propertyType.Name = property.Name; - propertyType.Description = property.Description; - propertyType.HelpText = property.HelpText; - propertyType.Mandatory = property.Mandatory; - propertyType.ValidationRegExp = property.ValidationRegExp; - propertyType.SortOrder = property.SortOrder; - - if (property.PropertyTypeGroupId.HasValue) - propertyType.PropertyGroupId = new Lazy(() => property.PropertyTypeGroupId.Value); - } - - private Dictionary GetStandardPropertyTypeStubs() - { - var propertyTypes = new Dictionary(); - - propertyTypes.Add(Constants.Conventions.Member.Comments, - new PropertyType(new Guid(Constants.PropertyEditors.TextboxMultiple), DataTypeDatabaseType.Ntext) - { - Alias = Constants.Conventions.Member.Comments, - Name = Constants.Conventions.Member.CommentsLabel - }); - - propertyTypes.Add(Constants.Conventions.Member.FailedPasswordAttempts, - new PropertyType(new Guid(Constants.PropertyEditors.Integer), DataTypeDatabaseType.Integer) - { - Alias = Constants.Conventions.Member.FailedPasswordAttempts, - Name = Constants.Conventions.Member.FailedPasswordAttemptsLabel - }); - - propertyTypes.Add(Constants.Conventions.Member.IsApproved, - new PropertyType(new Guid(Constants.PropertyEditors.TrueFalse), DataTypeDatabaseType.Integer) - { - Alias = Constants.Conventions.Member.IsApproved, - Name = Constants.Conventions.Member.IsApprovedLabel - }); - - propertyTypes.Add(Constants.Conventions.Member.IsLockedOut, - new PropertyType(new Guid(Constants.PropertyEditors.TrueFalse), DataTypeDatabaseType.Integer) - { - Alias = Constants.Conventions.Member.IsLockedOut, - Name = Constants.Conventions.Member.IsLockedOutLabel - }); - - propertyTypes.Add(Constants.Conventions.Member.LastLockoutDate, - new PropertyType(new Guid(Constants.PropertyEditors.Date), DataTypeDatabaseType.Date) - { - Alias = Constants.Conventions.Member.LastLockoutDate, - Name = Constants.Conventions.Member.LastLockoutDateLabel - }); - - propertyTypes.Add(Constants.Conventions.Member.LastLoginDate, - new PropertyType(new Guid(Constants.PropertyEditors.Date), DataTypeDatabaseType.Date) - { - Alias = Constants.Conventions.Member.LastLoginDate, - Name = Constants.Conventions.Member.LastLoginDateLabel - }); - - propertyTypes.Add(Constants.Conventions.Member.LastPasswordChangeDate, - new PropertyType(new Guid(Constants.PropertyEditors.Date), DataTypeDatabaseType.Date) - { - Alias = Constants.Conventions.Member.LastPasswordChangeDate, - Name = Constants.Conventions.Member.LastPasswordChangeDateLabel - }); - - propertyTypes.Add(Constants.Conventions.Member.PasswordAnswer, - new PropertyType(new Guid(Constants.PropertyEditors.Textbox), DataTypeDatabaseType.Nvarchar) - { - Alias = Constants.Conventions.Member.PasswordAnswer, - Name = Constants.Conventions.Member.PasswordAnswerLabel - }); - - propertyTypes.Add(Constants.Conventions.Member.PasswordQuestion, - new PropertyType(new Guid(Constants.PropertyEditors.Textbox), DataTypeDatabaseType.Nvarchar) - { - Alias = Constants.Conventions.Member.PasswordQuestion, - Name = Constants.Conventions.Member.PasswordQuestionLabel - }); - - return propertyTypes; - } } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Mappers/MappingResolver.cs b/src/Umbraco.Core/Persistence/Mappers/MappingResolver.cs index 9fa1846629..cb5d7c95a1 100644 --- a/src/Umbraco.Core/Persistence/Mappers/MappingResolver.cs +++ b/src/Umbraco.Core/Persistence/Mappers/MappingResolver.cs @@ -3,8 +3,6 @@ using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using Umbraco.Core.Logging; -using Umbraco.Core.Models; -using Umbraco.Core.Models.Membership; using Umbraco.Core.ObjectResolution; namespace Umbraco.Core.Persistence.Mappers diff --git a/src/Umbraco.Core/Persistence/Mappers/MemberMapper.cs b/src/Umbraco.Core/Persistence/Mappers/MemberMapper.cs index 6e93d7c4aa..d895e1c127 100644 --- a/src/Umbraco.Core/Persistence/Mappers/MemberMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/MemberMapper.cs @@ -1,6 +1,6 @@ using System.Collections.Concurrent; using Umbraco.Core.Models.EntityBase; -using Umbraco.Core.Models.Membership; +using Umbraco.Core.Models; using Umbraco.Core.Models.Rdbms; namespace Umbraco.Core.Persistence.Mappers @@ -41,7 +41,6 @@ namespace Umbraco.Core.Persistence.Mappers CacheMap(src => src.Name, dto => dto.Text); CacheMap(src => src.Trashed, dto => dto.Trashed); CacheMap(src => src.Key, dto => dto.UniqueId); - CacheMap(src => src.ProfileId, dto => dto.UniqueId); CacheMap(src => src.ContentTypeId, dto => dto.ContentTypeId); CacheMap(src => src.ContentTypeAlias, dto => dto.Alias); CacheMap(src => src.UpdateDate, dto => dto.VersionDate); diff --git a/src/Umbraco.Core/Persistence/Mappers/MemberTypeMapper.cs b/src/Umbraco.Core/Persistence/Mappers/MemberTypeMapper.cs index 27fb42a659..eafc1e5031 100644 --- a/src/Umbraco.Core/Persistence/Mappers/MemberTypeMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/MemberTypeMapper.cs @@ -1,5 +1,5 @@ using System.Collections.Concurrent; -using Umbraco.Core.Models.Membership; +using Umbraco.Core.Models; using Umbraco.Core.Models.Rdbms; namespace Umbraco.Core.Persistence.Mappers diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberRepository.cs index eb5d8fb049..be959da07c 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IMemberRepository.cs @@ -1,5 +1,5 @@ using System.Collections.Generic; -using Umbraco.Core.Models.Membership; +using Umbraco.Core.Models; namespace Umbraco.Core.Persistence.Repositories { diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs index a999cc8baa..fca06ad58a 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberRepository.cs @@ -5,7 +5,7 @@ using System.Linq; using Umbraco.Core.Configuration; using Umbraco.Core.IO; using Umbraco.Core.Models.EntityBase; -using Umbraco.Core.Models.Membership; +using Umbraco.Core.Models; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.Caching; using Umbraco.Core.Persistence.Factories; @@ -17,12 +17,17 @@ namespace Umbraco.Core.Persistence.Repositories { internal class MemberRepository : VersionableRepositoryBase, IMemberRepository { - public MemberRepository(IDatabaseUnitOfWork work) : base(work) + private readonly IMemberTypeRepository _memberTypeRepository; + + public MemberRepository(IDatabaseUnitOfWork work, IMemberTypeRepository memberTypeRepository) : base(work) { + _memberTypeRepository = memberTypeRepository; } - public MemberRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache) : base(work, cache) + public MemberRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache, IMemberTypeRepository memberTypeRepository) + : base(work, cache) { + _memberTypeRepository = memberTypeRepository; } #region Overrides of RepositoryBase @@ -402,9 +407,18 @@ namespace Umbraco.Core.Persistence.Repositories { if (dtos == null || dtos.Any() == false) return null; + var dto = dtos.First(); - var factory = new MemberReadOnlyFactory(); - var member = factory.BuildEntity(dtos.First()); + var memberTypes = new Dictionary + { + { + dto.ContentTypeAlias, + _memberTypeRepository.Get(dto.ContentTypeId) + } + }; + + var factory = new MemberReadOnlyFactory(memberTypes); + var member = factory.BuildEntity(dto); return member; } @@ -414,7 +428,12 @@ namespace Umbraco.Core.Persistence.Repositories if (dtos == null || dtos.Any() == false) return Enumerable.Empty(); - var factory = new MemberReadOnlyFactory(); + //We assume that there won't exist a lot of MemberTypes, so the following should be fairly fast + var memberTypes = new Dictionary(); + var memberTypeList = _memberTypeRepository.GetAll(); + memberTypeList.ForEach(x => memberTypes.Add(x.Alias, x)); + + var factory = new MemberReadOnlyFactory(memberTypes); return dtos.Select(factory.BuildEntity); } } diff --git a/src/Umbraco.Core/Persistence/RepositoryFactory.cs b/src/Umbraco.Core/Persistence/RepositoryFactory.cs index a94fd0a59e..6985e427fe 100644 --- a/src/Umbraco.Core/Persistence/RepositoryFactory.cs +++ b/src/Umbraco.Core/Persistence/RepositoryFactory.cs @@ -117,7 +117,7 @@ namespace Umbraco.Core.Persistence internal virtual IMemberRepository CreateMemberRepository(IDatabaseUnitOfWork uow) { - return new MemberRepository(uow, RuntimeCacheProvider.Current); + return new MemberRepository(uow, RuntimeCacheProvider.Current, CreateMemberTypeRepository(uow)); } internal virtual IMemberTypeRepository CreateMemberTypeRepository(IDatabaseUnitOfWork uow)