From a4adbca12c50ca0c1e15b9bfe8bbe107a19259e2 Mon Sep 17 00:00:00 2001 From: Shannon Date: Wed, 19 Feb 2014 21:56:33 +1100 Subject: [PATCH] Removes the ability to edit the data type for a built-in membership property. Ensures that even if a data type is attempted to be changed with the API that the built-in properties are always persisted with the data type that we have defined by convention. --- .../Factories/MemberTypeReadOnlyFactory.cs | 3 +- .../Repositories/ContentTypeBaseRepository.cs | 17 ++++++- .../Repositories/MemberTypeRepository.cs | 46 ++++++++++++++----- .../GenericProperties/GenericProperty.ascx.cs | 1 + src/umbraco.cms/businesslogic/ContentType.cs | 2 +- 5 files changed, 54 insertions(+), 15 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs b/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs index f0151ba06b..7fe64a3f33 100644 --- a/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/MemberTypeReadOnlyFactory.cs @@ -58,6 +58,7 @@ namespace Umbraco.Core.Persistence.Factories private PropertyGroupCollection GetPropertyTypeGroupCollection(MemberTypeReadOnlyDto dto, MemberType memberType) { var propertyGroups = new PropertyGroupCollection(); + var standardProps = Constants.Conventions.Member.GetStandardPropertyTypeStubs(); foreach (var groupDto in dto.PropertyTypeGroups.Where(x => x.Id.HasValue)) { var group = new PropertyGroup(); @@ -93,7 +94,7 @@ namespace Umbraco.Core.Persistence.Factories var propertyType = new PropertyType(typeDto.ControlId, //ensures that any built-in membership properties have their correct dbtype assigned no matter //what the underlying data type is - MemberTypeRepository.GetDbTypeForProperty(typeDto.Alias, typeDto.DbType.EnumParse(true))) + MemberTypeRepository.GetDbTypeForProperty(typeDto.Alias, typeDto.DbType.EnumParse(true), standardProps)) { Alias = typeDto.Alias, DataTypeDefinitionId = typeDto.DataTypeId, diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs index e2ea48b78c..fb700e4f30 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs @@ -302,8 +302,21 @@ namespace Umbraco.Core.Persistence.Repositories //If the Id of the DataType is not set, we resolve it from the db by its ControlId if (propertyType.DataTypeDefinitionId == 0 || propertyType.DataTypeDefinitionId == default(int)) { - var datatype = Database.FirstOrDefault("WHERE controlId = @Id", new { Id = propertyType.DataTypeId }); - propertyType.DataTypeDefinitionId = datatype.DataTypeId; + //we cannot try to assign a data type of it's an empty guid + if (propertyType.DataTypeId != Guid.Empty) + { + var sql = new Sql() + .Select("*") + .From() + .Where("controlId = @Id", new { Id = propertyType.DataTypeId }) + .OrderBy(typeDto => typeDto.DataTypeId); + var datatype = Database.FirstOrDefault(sql); + //we cannot assign a data type if one was not found + if (datatype != null) + { + propertyType.DataTypeDefinitionId = datatype.DataTypeId; + } + } } //validate the alias! diff --git a/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs index f0f9a3b20d..8ecc194d29 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MemberTypeRepository.cs @@ -179,10 +179,10 @@ namespace Umbraco.Core.Persistence.Repositories var factory = new MemberTypeFactory(NodeObjectTypeId); var dto = factory.BuildDto(entity); - PersistNewBaseContentType(dto, entity); - EnsureCorrectDbTypeForBuiltInProperties(entity); + PersistNewBaseContentType(dto, entity); + //Handles the MemberTypeDto (cmsMemberType table) var memberTypeDtos = factory.BuildMemberTypeDtos(entity); foreach (var memberTypeDto in memberTypeDtos) @@ -216,10 +216,10 @@ namespace Umbraco.Core.Persistence.Repositories var factory = new MemberTypeFactory(NodeObjectTypeId); var dto = factory.BuildDto(entity); - PersistUpdatedBaseContentType(dto, entity); - EnsureCorrectDbTypeForBuiltInProperties(entity); + PersistUpdatedBaseContentType(dto, entity); + //Remove existing entries before inserting new ones Database.Delete("WHERE NodeId = @Id", new {Id = entity.Id}); @@ -236,15 +236,19 @@ namespace Umbraco.Core.Persistence.Repositories #endregion /// - /// now we need to ensure that all the built-in membership provider properties have their correct db types - /// assigned, no matter what the underlying data type is + /// Ensure that all the built-in membership provider properties have their correct db types + /// and property editors assigned. /// /// private static void EnsureCorrectDbTypeForBuiltInProperties(IContentTypeBase memberType) { + var stdProps = Constants.Conventions.Member.GetStandardPropertyTypeStubs(); foreach (var propertyType in memberType.PropertyTypes) { - propertyType.DataTypeDatabaseType = GetDbTypeForProperty(propertyType.Alias, propertyType.DataTypeDatabaseType); + propertyType.DataTypeDatabaseType = GetDbTypeForProperty(propertyType.Alias, propertyType.DataTypeDatabaseType, stdProps); + //this reset's it's current data type reference which will be re-assigned based on the property editor assigned on the next line + propertyType.DataTypeDefinitionId = 0; + propertyType.DataTypeId = GetPropertyEditorForProperty(propertyType.Alias, propertyType.DataTypeId, stdProps); } } @@ -268,20 +272,40 @@ namespace Umbraco.Core.Persistence.Repositories /// /// /// + /// /// - internal static DataTypeDatabaseType GetDbTypeForProperty(string propAlias, DataTypeDatabaseType dbType) + internal static DataTypeDatabaseType GetDbTypeForProperty( + string propAlias, + DataTypeDatabaseType dbType, + Dictionary standardProps) { - var stdProps = Constants.Conventions.Member.GetStandardPropertyTypeStubs(); - var aliases = stdProps.Select(x => x.Key).ToArray(); + var aliases = standardProps.Select(x => x.Key).ToArray(); //check if it is built in if (aliases.Contains(propAlias)) { //return the pre-determined db type for this property - return stdProps.Single(x => x.Key == propAlias).Value.DataTypeDatabaseType; + return standardProps.Single(x => x.Key == propAlias).Value.DataTypeDatabaseType; } return dbType; } + + internal static Guid GetPropertyEditorForProperty( + string propAlias, + Guid propertyEditor, + Dictionary standardProps) + { + var aliases = standardProps.Select(x => x.Key).ToArray(); + + //check if it is built in + if (aliases.Contains(propAlias)) + { + //return the pre-determined db type for this property + return standardProps.Single(x => x.Key == propAlias).Value.DataTypeId; + } + + return propertyEditor; + } } } \ No newline at end of file diff --git a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/GenericProperties/GenericProperty.ascx.cs b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/GenericProperties/GenericProperty.ascx.cs index c9aaa5bc06..2ab2f5d763 100644 --- a/src/Umbraco.Web/umbraco.presentation/umbraco/controls/GenericProperties/GenericProperty.ascx.cs +++ b/src/Umbraco.Web/umbraco.presentation/umbraco/controls/GenericProperties/GenericProperty.ascx.cs @@ -158,6 +158,7 @@ namespace umbraco.controls.GenericProperties lblAlias.Visible = AllowPropertyEdit == false; PropertyPanel5.Visible = AllowPropertyEdit; PropertyPanel6.Visible = AllowPropertyEdit; + PropertyPanel3.Visible = AllowPropertyEdit; } else { diff --git a/src/umbraco.cms/businesslogic/ContentType.cs b/src/umbraco.cms/businesslogic/ContentType.cs index e10ac4aa25..6f9514f460 100644 --- a/src/umbraco.cms/businesslogic/ContentType.cs +++ b/src/umbraco.cms/businesslogic/ContentType.cs @@ -175,7 +175,7 @@ namespace umbraco.cms.businesslogic public static ContentType GetContentType(int id) { return ApplicationContext.Current.ApplicationCache.GetCacheItem - (string.Format("UmbracoContentType{0}", id), + (string.Format("{0}{1}", CacheKeys.ContentTypeCacheKey, id), TimeSpan.FromMinutes(30), () => new ContentType(id)); }