From 9f5a9f179f8e865e2b74368f8deb4976be7f358d Mon Sep 17 00:00:00 2001 From: Claus Date: Thu, 18 Aug 2016 11:17:05 +0200 Subject: [PATCH] U4-8866 Deleting a parent document type fails if any documents using a child document type exist ensures that we also manually delete content of any child content type being deleted, instead of only deleting content of the actual content type sent for delete. --- .../Services/ContentTypeService.cs | 34 +++++++++++-------- .../Services/ContentTypeServiceTests.cs | 29 ++++++++++++++++ 2 files changed, 49 insertions(+), 14 deletions(-) diff --git a/src/Umbraco.Core/Services/ContentTypeService.cs b/src/Umbraco.Core/Services/ContentTypeService.cs index 1ea43c0f08..d80a93a4ab 100644 --- a/src/Umbraco.Core/Services/ContentTypeService.cs +++ b/src/Umbraco.Core/Services/ContentTypeService.cs @@ -791,21 +791,23 @@ namespace Umbraco.Core.Services using (new WriteLock(Locker)) { - - //TODO: This needs to change, if we are deleting a content type, we should just delete the data, - // this method will recursively go lookup every content item, check if any of it's descendants are - // of a different type, move them to the recycle bin, then permanently delete the content items. - // The main problem with this is that for every content item being deleted, events are raised... - // which we need for many things like keeping caches in sync, but we can surely do this MUCH better. - - _contentService.DeleteContentOfType(contentType.Id); - var uow = UowProvider.GetUnitOfWork(); using (var repository = RepositoryFactory.CreateContentTypeRepository(uow)) { + //TODO: This needs to change, if we are deleting a content type, we should just delete the data, + // this method will recursively go lookup every content item, check if any of it's descendants are + // of a different type, move them to the recycle bin, then permanently delete the content items. + // The main problem with this is that for every content item being deleted, events are raised... + // which we need for many things like keeping caches in sync, but we can surely do this MUCH better. + var deletedContentTypes = new List() {contentType}; deletedContentTypes.AddRange(contentType.Descendants().OfType()); + foreach (var deletedContentType in deletedContentTypes) + { + _contentService.DeleteContentOfType(deletedContentType.Id); + } + repository.Delete(contentType); uow.Commit(); @@ -833,11 +835,6 @@ namespace Umbraco.Core.Services using (new WriteLock(Locker)) { - foreach (var contentType in asArray) - { - _contentService.DeleteContentOfType(contentType.Id); - } - var uow = UowProvider.GetUnitOfWork(); using (var repository = RepositoryFactory.CreateContentTypeRepository(uow)) { @@ -847,6 +844,15 @@ namespace Umbraco.Core.Services foreach (var contentType in asArray) { deletedContentTypes.AddRange(contentType.Descendants().OfType()); + } + + foreach (var deletedContentType in deletedContentTypes) + { + _contentService.DeleteContentOfType(deletedContentType.Id); + } + + foreach (var contentType in asArray) + { repository.Delete(contentType); } diff --git a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs index bf752aa601..bc9ec8a9ad 100644 --- a/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs +++ b/src/Umbraco.Tests/Services/ContentTypeServiceTests.cs @@ -275,6 +275,35 @@ namespace Umbraco.Tests.Services Assert.That(success, Is.False); } + [Test] + public void Can_Delete_Parent_ContentType_When_Child_Has_Content() + { + var cts = ServiceContext.ContentTypeService; + var contentType = MockedContentTypes.CreateSimpleContentType("page", "Page", null, true); + cts.Save(contentType); + var childContentType = MockedContentTypes.CreateSimpleContentType("childPage", "Child Page", contentType, true, "Child Content"); + cts.Save(childContentType); + var cs = ServiceContext.ContentService; + var content = cs.CreateContent("Page 1", -1, childContentType.Alias); + cs.Save(content); + + cts.Delete(contentType); + + Assert.IsNotNull(content.Id); + Assert.AreNotEqual(0, content.Id); + Assert.IsNotNull(childContentType.Id); + Assert.AreNotEqual(0, childContentType.Id); + Assert.IsNotNull(contentType.Id); + Assert.AreNotEqual(0, contentType.Id); + var deletedContent = cs.GetById(content.Id); + var deletedChildContentType = cts.GetContentType(childContentType.Id); + var deletedContentType = cts.GetContentType(contentType.Id); + + Assert.IsNull(deletedChildContentType); + Assert.IsNull(deletedContent); + Assert.IsNull(deletedContentType); + } + [Test] public void Deleting_ContentType_Sends_Correct_Number_Of_DeletedEntities_In_Events() {