From 8a32f02781a67d4b9b7f7603c6f07759921d680e Mon Sep 17 00:00:00 2001 From: leekelleher Date: Sun, 4 Jan 2015 20:46:00 +0000 Subject: [PATCH] Added custom event handler to create the relation for trashed nodes. Removed the additional (AJAX) resource call from the Angular controller, as the relation removal is handled in server-side code during the move. --- src/Umbraco.Core/Services/ContentService.cs | 3 - .../content/content.restore.controller.js | 21 +++--- .../Strategies/RelateOnTrashHandler.cs | 65 +++++++++++++++++++ src/Umbraco.Web/Umbraco.Web.csproj | 1 + 4 files changed, 78 insertions(+), 12 deletions(-) create mode 100644 src/Umbraco.Web/Strategies/RelateOnTrashHandler.cs diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index c21c4f6871..421beacbf7 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -1131,9 +1131,6 @@ namespace Umbraco.Core.Services return; } - // Add a relation for the item being deleted, so that we can know the original parent for if we need to restore later - ApplicationContext.Current.Services.RelationService.Relate(content.Parent(), content, Constants.Conventions.Relations.RelateParentDocumentOnDelete); - var moveInfo = new List> { new MoveEventInfo(content, originalPath, Constants.System.RecycleBinContent) diff --git a/src/Umbraco.Web.UI.Client/src/views/content/content.restore.controller.js b/src/Umbraco.Web.UI.Client/src/views/content/content.restore.controller.js index 59800afe09..0f492e74be 100644 --- a/src/Umbraco.Web.UI.Client/src/views/content/content.restore.controller.js +++ b/src/Umbraco.Web.UI.Client/src/views/content/content.restore.controller.js @@ -7,13 +7,18 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController" relationResource.getByChildId(node.id, "relateParentDocumentOnDelete").then(function (data) { $scope.relation = data[0]; - contentResource.getById($scope.relation.ParentId).then(function (data) { - $scope.target = data; + if ($scope.relation.ParentId == -1) { + $scope.target = { id: -1, name: "Root" }; - }, function (err) { - $scope.success = false; - $scope.error = err; - }); + } else { + contentResource.getById($scope.relation.ParentId).then(function (data) { + $scope.target = data; + + }, function (err) { + $scope.success = false; + $scope.error = err; + }); + } }, function (err) { $scope.success = false; @@ -21,6 +26,7 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController" }); $scope.restore = function () { + // this code was copied from `content.move.controller.js` contentResource.move({ parentId: $scope.target.id, id: node.id }) .then(function (path) { $scope.error = false; @@ -43,9 +49,6 @@ angular.module("umbraco").controller("Umbraco.Editors.Content.RestoreController" } }); - // remove the relation, as the item has been restored - relationResource.deleteById($scope.relation.Id); - }, function (err) { $scope.success = false; $scope.error = err; diff --git a/src/Umbraco.Web/Strategies/RelateOnTrashHandler.cs b/src/Umbraco.Web/Strategies/RelateOnTrashHandler.cs new file mode 100644 index 0000000000..8b3cd598a2 --- /dev/null +++ b/src/Umbraco.Web/Strategies/RelateOnTrashHandler.cs @@ -0,0 +1,65 @@ +using System; +using System.Linq; +using Umbraco.Core; +using Umbraco.Core.Auditing; +using Umbraco.Core.Events; +using Umbraco.Core.Models; +using Umbraco.Core.Services; + +namespace Umbraco.Web.Strategies +{ + public sealed class RelateOnTrashHandler : ApplicationEventHandler + { + protected override void ApplicationStarting(UmbracoApplicationBase umbracoApplication, ApplicationContext applicationContext) + { + ContentService.Moved += ContentService_Moved; + ContentService.Trashed += ContentService_Trashed; + } + + private void ContentService_Moved(IContentService sender, MoveEventArgs e) + { + foreach (var item in e.MoveInfoCollection.Where(x => x.OriginalPath.Contains(Constants.System.RecycleBinContent.ToInvariantString()))) + { + var relationService = ApplicationContext.Current.Services.RelationService; + var relationTypeAlias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias; + var relations = relationService.GetByChildId(item.Entity.Id); + + foreach (var relation in relations.Where(x => x.RelationType.Alias.InvariantEquals(relationTypeAlias))) + { + relationService.Delete(relation); + } + } + } + + private void ContentService_Trashed(IContentService sender, MoveEventArgs e) + { + var relationService = ApplicationContext.Current.Services.RelationService; + var relationTypeAlias = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteAlias; + var relationType = relationService.GetRelationTypeByAlias(relationTypeAlias); + + // check that the relation-type exists, if not, then recreate it + if (relationType == null) + { + var documentObjectType = new Guid(Constants.ObjectTypes.Document); + var relationTypeName = Constants.Conventions.RelationTypes.RelateParentDocumentOnDeleteName; + + relationType = new RelationType(documentObjectType, documentObjectType, relationTypeAlias, relationTypeName); + relationService.Save(relationType); + } + + foreach (var item in e.MoveInfoCollection) + { + var originalPath = item.OriginalPath.ToDelimitedList(); + var originalParentId = originalPath.Count > 2 + ? int.Parse(originalPath[originalPath.Count - 2]) + : Constants.System.Root; + + // Add a relation for the item being deleted, so that we can know the original parent for if we need to restore later + var relation = new Relation(originalParentId, item.Entity.Id, relationType); + relationService.Save(relation); + + Audit.Add(AuditTypes.Delete, string.Format("Trashed content with Id: '{0}' related to original parent content with Id: '{1}'", item.Entity.Id, originalParentId), item.Entity.WriterId, item.Entity.Id); + } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 24895c7bd7..5f24703a14 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -494,6 +494,7 @@ +