diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs index 21fb9842d9..b88b928e9c 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentTypeBaseRepository.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Data; using System.Globalization; using System.Linq; using System.Threading.Tasks; @@ -11,6 +12,7 @@ using Umbraco.Core.Persistence.Caching; using Umbraco.Core.Persistence.Factories; using Umbraco.Core.Persistence.Querying; using Umbraco.Core.Persistence.Relators; +using Umbraco.Core.Persistence.SqlSyntax; using Umbraco.Core.Persistence.UnitOfWork; namespace Umbraco.Core.Persistence.Repositories @@ -63,6 +65,17 @@ namespace Umbraco.Core.Persistence.Repositories protected void PersistNewBaseContentType(ContentTypeDto dto, IContentTypeComposition entity) { + //Cannot add a duplicate content type type + var exists = Database.ExecuteScalar(@"SELECT COUNT(*) FROM cmsContentType +INNER JOIN umbracoNode ON cmsContentType.nodeId = umbracoNode.id +WHERE cmsContentType." + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("alias") + @"= @alias +AND umbracoNode.nodeObjectType = @objectType", + new { alias = entity.Alias, objectType = NodeObjectTypeId }); + if (exists > 0) + { + throw new DuplicateNameException("An item with the alias " + entity.Alias + " already exists"); + } + //Logic for setting Path, Level and SortOrder var parent = Database.First("WHERE id = @ParentId", new { ParentId = entity.ParentId }); int level = parent.Level + 1; @@ -165,6 +178,19 @@ namespace Umbraco.Core.Persistence.Repositories protected void PersistUpdatedBaseContentType(ContentTypeDto dto, IContentTypeComposition entity) { + + //Cannot update to a duplicate alias + var exists = Database.ExecuteScalar(@"SELECT COUNT(*) FROM cmsContentType +INNER JOIN umbracoNode ON cmsContentType.nodeId = umbracoNode.id +WHERE cmsContentType." + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("alias") + @"= @alias +AND umbracoNode.nodeObjectType = @objectType +AND umbracoNode.id <> @id", + new { id = dto.NodeId, alias = entity.Alias, objectType = NodeObjectTypeId }); + if (exists > 0) + { + throw new DuplicateNameException("An item with the alias " + entity.Alias + " already exists"); + } + var propertyGroupFactory = new PropertyGroupFactory(entity.Id); var nodeDto = dto.NodeDto; diff --git a/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs b/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs index d8bfe62deb..3798bb53d9 100644 --- a/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/DataTypeDefinitionRepository.cs @@ -165,6 +165,18 @@ WHERE umbracoNode." + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("te protected override void PersistUpdatedItem(IDataTypeDefinition entity) { + + //Cannot change to a duplicate alias + var exists = Database.ExecuteScalar(@"SELECT COUNT(*) FROM cmsDataType +INNER JOIN umbracoNode ON cmsDataType.nodeId = umbracoNode.id +WHERE umbracoNode." + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("text") + @"= @name +AND umbracoNode.id <> @id", + new { id = entity.Id, name = entity.Name }); + if (exists > 0) + { + throw new DuplicateNameException("A data type with the name " + entity.Name + " already exists"); + } + //Updates Modified date and Version Guid ((DataTypeDefinition)entity).UpdatingEntity(); diff --git a/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs index f14a88ba74..0932cc89b2 100644 --- a/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/RepositoryBase.cs @@ -223,8 +223,19 @@ namespace Umbraco.Core.Persistence.Repositories /// public virtual void PersistNewItem(IEntity entity) { - PersistNewItem((TEntity)entity); - _cache.Save(typeof(TEntity), entity); + try + { + PersistNewItem((TEntity)entity); + _cache.Save(typeof(TEntity), entity); + } + catch (Exception) + { + //if an exception is thrown we need to remove the entry from cache, this is ONLY a work around because of the way + // that we cache entities: http://issues.umbraco.org/issue/U4-4259 + _cache.Delete(typeof (TEntity), entity); + throw; + } + } /// @@ -233,8 +244,19 @@ namespace Umbraco.Core.Persistence.Repositories /// public virtual void PersistUpdatedItem(IEntity entity) { - PersistUpdatedItem((TEntity)entity); - _cache.Save(typeof(TEntity), entity); + try + { + PersistUpdatedItem((TEntity)entity); + _cache.Save(typeof(TEntity), entity); + } + catch (Exception) + { + //if an exception is thrown we need to remove the entry from cache, this is ONLY a work around because of the way + // that we cache entities: http://issues.umbraco.org/issue/U4-4259 + _cache.Delete(typeof (TEntity), entity); + throw; + } + } /// diff --git a/src/Umbraco.Tests/Membership/UmbracoServiceMembershipProviderTests.cs b/src/Umbraco.Tests/Membership/UmbracoServiceMembershipProviderTests.cs index 64305d6b1c..99ec6dbef2 100644 --- a/src/Umbraco.Tests/Membership/UmbracoServiceMembershipProviderTests.cs +++ b/src/Umbraco.Tests/Membership/UmbracoServiceMembershipProviderTests.cs @@ -95,7 +95,7 @@ namespace Umbraco.Tests.Membership mServiceMock.Setup(service => service.GetDefaultMemberType()).Returns("Member"); mServiceMock.Setup( service => service.CreateWithIdentity(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((string u, string e, string p, string m, bool b) => + .Callback((string u, string e, string p, string m) => { createdMember = new Member("test", e, u, p, memberType); }) @@ -126,7 +126,7 @@ namespace Umbraco.Tests.Membership mServiceMock.Setup(service => service.GetDefaultMemberType()).Returns("Member"); mServiceMock.Setup( service => service.CreateWithIdentity(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((string u, string e, string p, string m, bool b) => + .Callback((string u, string e, string p, string m) => { createdMember = new Member("test", e, u, p, memberType); }) @@ -159,7 +159,7 @@ namespace Umbraco.Tests.Membership mServiceMock.Setup(service => service.GetDefaultMemberType()).Returns("Member"); mServiceMock.Setup( service => service.CreateWithIdentity(It.IsAny(), It.IsAny(), It.IsAny(), It.IsAny())) - .Callback((string u, string e, string p, string m, bool b) => + .Callback((string u, string e, string p, string m) => { createdMember = new Member("test", e, u, p, memberType); }) diff --git a/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx b/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx index 16f5ba6d53..3a9bd18b96 100644 --- a/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx +++ b/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx @@ -52,7 +52,8 @@ - + + diff --git a/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx.cs b/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx.cs index c3459b752e..28250d9fa4 100644 --- a/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx.cs +++ b/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Web; +using System.Web.UI.WebControls; namespace Umbraco.Web.UI.Umbraco.Controls { diff --git a/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx.designer.cs b/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx.designer.cs index 582c67837d..c17c27becf 100644 --- a/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx.designer.cs +++ b/src/Umbraco.Web.UI/umbraco/controls/ContentTypeControlNew.ascx.designer.cs @@ -11,5 +11,7 @@ namespace Umbraco.Web.UI.Umbraco.Controls { public partial class ContentTypeControlNew { + + } } diff --git a/src/Umbraco.Web.UI/umbraco/create/simple.ascx b/src/Umbraco.Web.UI/umbraco/create/simple.ascx index 4a965a4eb1..a057cb3d98 100644 --- a/src/Umbraco.Web.UI/umbraco/create/simple.ascx +++ b/src/Umbraco.Web.UI/umbraco/create/simple.ascx @@ -17,6 +17,6 @@ public override void Save() { + //Cannot change to a duplicate alias + var exists = Database.ExecuteScalar(@"SELECT COUNT(*) FROM cmsDataType +INNER JOIN umbracoNode ON cmsDataType.nodeId = umbracoNode.id +WHERE umbracoNode." + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("text") + @"= @name +AND umbracoNode.id <> @id", + new { id = this.Id, name = this.Text }); + if (exists > 0) + { + ApplicationContext.Current.ApplicationCache.RuntimeCache.ClearCacheItem( + string.Format("{0}{1}", CacheKeys.DataTypeCacheKey, this.Id)); + + throw new DuplicateNameException("A data type with the name " + this.Text + " already exists"); + } + + //this actually does the persisting. + base.Text = _text1; + OnSaving(EventArgs.Empty); } diff --git a/src/umbraco.cms/businesslogic/media/MediaType.cs b/src/umbraco.cms/businesslogic/media/MediaType.cs index c597774472..5f00c9388a 100644 --- a/src/umbraco.cms/businesslogic/media/MediaType.cs +++ b/src/umbraco.cms/businesslogic/media/MediaType.cs @@ -91,12 +91,12 @@ namespace umbraco.cms.businesslogic.media /// The name of the MediaType /// The new MediaType [Obsolete("Obsolete, Use Umbraco.Core.Models.MediaType and Umbraco.Core.Services.ContentTypeService.Save()", false)] - public static MediaType MakeNew(BusinessLogic.User u, string Text) + public static MediaType MakeNew(User u, string Text) { return MakeNew(u, Text, -1); } - internal static MediaType MakeNew(BusinessLogic.User u, string text, int parentId) + internal static MediaType MakeNew(User u, string text, int parentId) { var mediaType = new Umbraco.Core.Models.MediaType(parentId) { Name = text, Alias = text, CreatorId = u.Id, Thumbnail = "folder.png", Icon = "folder.gif" }; ApplicationContext.Current.Services.ContentTypeService.Save(mediaType, u.Id);