From 9ef07ed2eb2a2b5da0e616d2001325d517a423b2 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Fri, 18 Jan 2013 10:56:14 -0100 Subject: [PATCH 1/2] Fixes U4-1214 and U4-1484 for both Content and Media --- .../Repositories/ContentRepository.cs | 1 + .../Repositories/MediaRepository.cs | 1 + src/Umbraco.Core/Services/ContentService.cs | 130 ++++++++++++------ src/Umbraco.Core/Services/MediaService.cs | 36 +++++ 4 files changed, 126 insertions(+), 42 deletions(-) diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index f699b8fec4..b284a4550a 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -280,6 +280,7 @@ namespace Umbraco.Core.Persistence.Repositories { var parent = Database.First("WHERE id = @ParentId", new { ParentId = entity.ParentId }); entity.Path = string.Concat(parent.Path, ",", entity.Id); + entity.Level = parent.Level + 1; var maxSortOrder = Database.ExecuteScalar("SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId", new { ParentId = entity.ParentId }); entity.SortOrder = maxSortOrder; } diff --git a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs index 9731e92610..33a7a35e9f 100644 --- a/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/MediaRepository.cs @@ -245,6 +245,7 @@ namespace Umbraco.Core.Persistence.Repositories { var parent = Database.First("WHERE id = @ParentId", new { ParentId = entity.ParentId }); entity.Path = string.Concat(parent.Path, ",", entity.Id); + entity.Level = parent.Level + 1; var maxSortOrder = Database.ExecuteScalar("SELECT coalesce(max(sortOrder),0) FROM umbracoNode WHERE parentid = @ParentId", new { ParentId = entity.ParentId }); entity.SortOrder = maxSortOrder; } diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index 87409151e3..b225a3a5cb 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -894,56 +894,76 @@ namespace Umbraco.Core.Services } /// - /// Moves an object to a new location by changing its parent id. - /// - /// - /// If the object is already published it will be - /// published after being moved to its new location. Otherwise it'll just - /// be saved with a new parent id. - /// - /// The to move - /// Id of the Content's new Parent - /// Optional Id of the User moving the Content - public void Move(IContent content, int parentId, int userId = -1) - { - //This ensures that the correct method is called if this method is used to Move to recycle bin. - if (parentId == -20) - { - MoveToRecycleBin(content, userId); - return; - } + /// Moves an object to a new location by changing its parent id. + /// + /// + /// If the object is already published it will be + /// published after being moved to its new location. Otherwise it'll just + /// be saved with a new parent id. + /// + /// The to move + /// Id of the Content's new Parent + /// Optional Id of the User moving the Content + public void Move(IContent content, int parentId, int userId = -1) + { + //This ensures that the correct method is called if this method is used to Move to recycle bin. + if (parentId == -20) + { + MoveToRecycleBin(content, userId); + return; + } - if (Moving.IsRaisedEventCancelled(new MoveEventArgs(content, parentId), this)) - return; - - SetWriter(content, userId); + if (Moving.IsRaisedEventCancelled(new MoveEventArgs(content, parentId), this)) + return; - //If Content is being moved away from Recycle Bin, its state should be un-trashed - if (content.Trashed && parentId != -20) - { - content.ChangeTrashedState(false, parentId); - } - else - { - content.ParentId = parentId; - } + SetWriter(content, userId); - //If Content is published, it should be (re)published from its new location - if (content.Published) - { - SaveAndPublish(content, userId); - } - else - { - Save(content, userId); - } + //If Content is being moved away from Recycle Bin, its state should be un-trashed + if (content.Trashed && parentId != -20) + { + content.ChangeTrashedState(false, parentId); + } + else + { + content.ParentId = parentId; + } - Moved.RaiseEvent(new MoveEventArgs(content, false, parentId), this); + //If Content is published, it should be (re)published from its new location + if (content.Published) + { + SaveAndPublish(content, userId); + } + else + { + Save(content, userId); + } + + //Ensure that Path and Level is updated on children + var children = GetChildren(content.Id); + if (children.Any()) + { + var parentPath = content.Path; + var parentLevel = content.Level; + var updatedDescendents = UpdatePathAndLevelOnChildren(children, parentPath, parentLevel); + + //collection of descendents that needs to be saved and published + var descendentsToSaveAndPublish = updatedDescendents.Where(x => x.Published); + foreach (var c in descendentsToSaveAndPublish) + { + SaveAndPublish(c, userId); + } + + //collection of descendents that only needs to be saved + var descendentsToSave = updatedDescendents.Where(x => x.Published == false); + Save(descendentsToSave, userId); + } + + Moved.RaiseEvent(new MoveEventArgs(content, false, parentId), this); Audit.Add(AuditTypes.Move, "Move Content performed by user", userId == -1 ? 0 : userId, content.Id); } - /// + /// /// Empties the Recycle Bin by deleting all that resides in the bin /// public void EmptyRecycleBin() @@ -1202,6 +1222,32 @@ namespace Umbraco.Core.Services return true; } + /// + /// Updates the Path and Level on a collection of objects + /// based on the Parent's Path and Level. + /// + /// Collection of objects to update + /// Path of the Parent content + /// Level of the Parent content + /// Collection of updated objects + private List UpdatePathAndLevelOnChildren(IEnumerable children, string parentPath, int parentLevel) + { + var list = new List(); + foreach (var child in children) + { + child.Path = string.Concat(parentPath, ",", child.Id); + child.Level = parentLevel + 1; + list.Add(child); + + var grandkids = GetChildren(child.Id); + if (grandkids.Any()) + { + list.AddRange(UpdatePathAndLevelOnChildren(grandkids, child.Path, child.Level)); + } + } + return list; + } + /// /// Updates a content object with the User (id), who created the content. /// diff --git a/src/Umbraco.Core/Services/MediaService.cs b/src/Umbraco.Core/Services/MediaService.cs index c456f5d95e..bb5d0ac844 100644 --- a/src/Umbraco.Core/Services/MediaService.cs +++ b/src/Umbraco.Core/Services/MediaService.cs @@ -276,6 +276,16 @@ namespace Umbraco.Core.Services media.ParentId = parentId; Save(media, userId); + //Ensure that Path and Level is updated on children + var children = GetChildren(media.Id); + if (children.Any()) + { + var parentPath = media.Path; + var parentLevel = media.Level; + var updatedDescendents = UpdatePathAndLevelOnChildren(children, parentPath, parentLevel); + Save(updatedDescendents, userId); + } + Moved.RaiseEvent(new MoveEventArgs(media, false, parentId), this); Audit.Add(AuditTypes.Move, "Move Media performed by user", userId == -1 ? 0 : userId, media.Id); @@ -513,6 +523,32 @@ namespace Umbraco.Core.Services _httpContext = httpContext; } + /// + /// Updates the Path and Level on a collection of objects + /// based on the Parent's Path and Level. + /// + /// Collection of objects to update + /// Path of the Parent media + /// Level of the Parent media + /// Collection of updated objects + private List UpdatePathAndLevelOnChildren(IEnumerable children, string parentPath, int parentLevel) + { + var list = new List(); + foreach (var child in children) + { + child.Path = string.Concat(parentPath, ",", child.Id); + child.Level = parentLevel + 1; + list.Add(child); + + var grandkids = GetChildren(child.Id); + if (grandkids.Any()) + { + list.AddRange(UpdatePathAndLevelOnChildren(grandkids, child.Path, child.Level)); + } + } + return list; + } + /// /// Updates a media object with the User (id), who created the content. /// From 0292ca9bf3ed88de1044ff42e0cdfcd6530b4436 Mon Sep 17 00:00:00 2001 From: Morten Christensen Date: Fri, 18 Jan 2013 11:18:19 -0100 Subject: [PATCH 2/2] Fixes issue with duplicated tags on inherited doc types. --- src/umbraco.cms/businesslogic/ContentType.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/umbraco.cms/businesslogic/ContentType.cs b/src/umbraco.cms/businesslogic/ContentType.cs index 59652b27a2..f0ee6bf8f7 100644 --- a/src/umbraco.cms/businesslogic/ContentType.cs +++ b/src/umbraco.cms/businesslogic/ContentType.cs @@ -1224,7 +1224,7 @@ namespace umbraco.cms.businesslogic temporaryList.Sort((a, b) => a.SortOrder.CompareTo(b.SortOrder)); // now that we aren't going to modify the list, we can set it to the class-scoped variable. - m_VirtualTabs = temporaryList; + m_VirtualTabs = temporaryList.DistinctBy(x => x.Id).ToList(); } private void populateMasterContentTypes(PropertyType pt, int docTypeId)