diff --git a/src/Umbraco.Core/Events/MoveEventInfo.cs b/src/Umbraco.Core/Events/MoveEventInfo.cs index 92c09c92a8..96f1e8ac7f 100644 --- a/src/Umbraco.Core/Events/MoveEventInfo.cs +++ b/src/Umbraco.Core/Events/MoveEventInfo.cs @@ -1,57 +1,28 @@ namespace Umbraco.Cms.Core.Events; -public class MoveEventInfo : IEquatable> +public class MoveEventInfo : MoveEventInfoBase { - public MoveEventInfo(TEntity entity, string originalPath, int newParentId) + public MoveEventInfo(TEntity entity, string originalPath, int newParentId, Guid? newParentKey) + : base(entity, originalPath) { - Entity = entity; - OriginalPath = originalPath; NewParentId = newParentId; + NewParentKey = newParentKey; } - public TEntity Entity { get; set; } - - public string OriginalPath { get; set; } + public MoveEventInfo(TEntity entity, string originalPath, int newParentId) : this(entity, originalPath, newParentId, null) + { + } + [Obsolete("Please use NewParentKey instead, scheduled for removal in V15")] public int NewParentId { get; set; } + public Guid? NewParentKey { get; } + public static bool operator ==(MoveEventInfo left, MoveEventInfo right) => Equals(left, right); - public bool Equals(MoveEventInfo? other) - { - if (ReferenceEquals(null, other)) - { - return false; - } + public override bool Equals(object? obj) => Equals((MoveEventInfo?)obj); - if (ReferenceEquals(this, other)) - { - return true; - } - - return EqualityComparer.Default.Equals(Entity, other.Entity) && NewParentId == other.NewParentId && - string.Equals(OriginalPath, other.OriginalPath); - } - - public override bool Equals(object? obj) - { - if (ReferenceEquals(null, obj)) - { - return false; - } - - if (ReferenceEquals(this, obj)) - { - return true; - } - - if (obj.GetType() != GetType()) - { - return false; - } - - return Equals((MoveEventInfo)obj); - } + public bool Equals(MoveEventInfo? other) => NewParentId == other?.NewParentId && NewParentKey == other.NewParentKey && base.Equals(other); public override int GetHashCode() { diff --git a/src/Umbraco.Core/Events/MoveEventInfoBase.cs b/src/Umbraco.Core/Events/MoveEventInfoBase.cs new file mode 100644 index 0000000000..4a20cfd39b --- /dev/null +++ b/src/Umbraco.Core/Events/MoveEventInfoBase.cs @@ -0,0 +1,38 @@ +namespace Umbraco.Cms.Core.Events; + +public abstract class MoveEventInfoBase : IEquatable> +{ + public MoveEventInfoBase(TEntity entity, string originalPath) + { + Entity = entity; + OriginalPath = originalPath; + } + + public TEntity Entity { get; set; } + + public string OriginalPath { get; set; } + + public bool Equals(MoveEventInfoBase? other) + { + if (ReferenceEquals(null, other)) + { + return false; + } + + if (ReferenceEquals(this, other)) + { + return true; + } + + if (other.GetType() != this.GetType()) + { + return false; + } + + return EqualityComparer.Default.Equals(Entity, other.Entity) && OriginalPath == other.OriginalPath; + } + + public override bool Equals(object? obj) => Equals((MoveEventInfoBase?) obj); + + public override int GetHashCode() => HashCode.Combine(Entity, OriginalPath); +} diff --git a/src/Umbraco.Core/Events/MoveToRecycleBinEventInfo.cs b/src/Umbraco.Core/Events/MoveToRecycleBinEventInfo.cs new file mode 100644 index 0000000000..16af79098a --- /dev/null +++ b/src/Umbraco.Core/Events/MoveToRecycleBinEventInfo.cs @@ -0,0 +1,8 @@ +namespace Umbraco.Cms.Core.Events; + +public class MoveToRecycleBinEventInfo : MoveEventInfoBase +{ + public MoveToRecycleBinEventInfo(TEntity entity, string originalPath) : base(entity, originalPath) + { + } +} diff --git a/src/Umbraco.Core/Notifications/ContentCopiedNotification.cs b/src/Umbraco.Core/Notifications/ContentCopiedNotification.cs index a5c6ede432..6bf525cbb2 100644 --- a/src/Umbraco.Core/Notifications/ContentCopiedNotification.cs +++ b/src/Umbraco.Core/Notifications/ContentCopiedNotification.cs @@ -8,8 +8,14 @@ namespace Umbraco.Cms.Core.Notifications; public sealed class ContentCopiedNotification : CopiedNotification { + public ContentCopiedNotification(IContent original, IContent copy, int parentId, Guid? parentKey, bool relateToOriginal, EventMessages messages) + : base(original, copy, parentId, parentKey, relateToOriginal, messages) + { + } + + [Obsolete("Please use constructor that takes a parent key as well, scheduled for removal in v15")] public ContentCopiedNotification(IContent original, IContent copy, int parentId, bool relateToOriginal, EventMessages messages) - : base(original, copy, parentId, relateToOriginal, messages) + : this(original, copy, parentId, null, relateToOriginal, messages) { } } diff --git a/src/Umbraco.Core/Notifications/ContentCopyingNotification.cs b/src/Umbraco.Core/Notifications/ContentCopyingNotification.cs index ef8eb48058..b905869353 100644 --- a/src/Umbraco.Core/Notifications/ContentCopyingNotification.cs +++ b/src/Umbraco.Core/Notifications/ContentCopyingNotification.cs @@ -8,8 +8,14 @@ namespace Umbraco.Cms.Core.Notifications; public sealed class ContentCopyingNotification : CopyingNotification { + public ContentCopyingNotification(IContent original, IContent copy, int parentId, Guid? parentKey, EventMessages messages) + : base(original, copy, parentId, parentKey, messages) + { + } + + [Obsolete("Please use constructor that takes a parent key as well, scheduled for removal in v15")] public ContentCopyingNotification(IContent original, IContent copy, int parentId, EventMessages messages) - : base(original, copy, parentId, messages) + : this(original, copy, parentId, null, messages) { } } diff --git a/src/Umbraco.Core/Notifications/ContentMovedToRecycleBinNotification.cs b/src/Umbraco.Core/Notifications/ContentMovedToRecycleBinNotification.cs index bf5415d9d1..6f4a6cea5a 100644 --- a/src/Umbraco.Core/Notifications/ContentMovedToRecycleBinNotification.cs +++ b/src/Umbraco.Core/Notifications/ContentMovedToRecycleBinNotification.cs @@ -8,14 +8,14 @@ namespace Umbraco.Cms.Core.Notifications; public sealed class ContentMovedToRecycleBinNotification : MovedToRecycleBinNotification { - public ContentMovedToRecycleBinNotification(MoveEventInfo target, EventMessages messages) + public ContentMovedToRecycleBinNotification(MoveToRecycleBinEventInfo target, EventMessages messages) : base( target, messages) { } - public ContentMovedToRecycleBinNotification(IEnumerable> target, EventMessages messages) + public ContentMovedToRecycleBinNotification(IEnumerable> target, EventMessages messages) : base(target, messages) { } diff --git a/src/Umbraco.Core/Notifications/ContentMovingToRecycleBinNotification.cs b/src/Umbraco.Core/Notifications/ContentMovingToRecycleBinNotification.cs index 5a691c6487..91ef7dd91c 100644 --- a/src/Umbraco.Core/Notifications/ContentMovingToRecycleBinNotification.cs +++ b/src/Umbraco.Core/Notifications/ContentMovingToRecycleBinNotification.cs @@ -8,14 +8,14 @@ namespace Umbraco.Cms.Core.Notifications; public sealed class ContentMovingToRecycleBinNotification : MovingToRecycleBinNotification { - public ContentMovingToRecycleBinNotification(MoveEventInfo target, EventMessages messages) + public ContentMovingToRecycleBinNotification(MoveToRecycleBinEventInfo target, EventMessages messages) : base( target, messages) { } - public ContentMovingToRecycleBinNotification(IEnumerable> target, EventMessages messages) + public ContentMovingToRecycleBinNotification(IEnumerable> target, EventMessages messages) : base(target, messages) { } diff --git a/src/Umbraco.Core/Notifications/CopiedNotification.cs b/src/Umbraco.Core/Notifications/CopiedNotification.cs index 13b9cf25ba..ddb1274e10 100644 --- a/src/Umbraco.Core/Notifications/CopiedNotification.cs +++ b/src/Umbraco.Core/Notifications/CopiedNotification.cs @@ -8,19 +8,29 @@ namespace Umbraco.Cms.Core.Notifications; public abstract class CopiedNotification : ObjectNotification where T : class { - protected CopiedNotification(T original, T copy, int parentId, bool relateToOriginal, EventMessages messages) + protected CopiedNotification(T original, T copy, int parentId, Guid? parentKey, bool relateToOriginal, EventMessages messages) : base(original, messages) { Copy = copy; ParentId = parentId; + ParentKey = parentKey; RelateToOriginal = relateToOriginal; } + [Obsolete("Please use constructor that takes a parent key, scheduled for removal in V15")] + protected CopiedNotification(T original, T copy, int parentId, bool relateToOriginal, EventMessages messages) + : this(original, copy, parentId, null, relateToOriginal, messages) + { + } + public T Original => Target; public T Copy { get; } + [Obsolete("Please use parent key instead, scheduled for removal in V15")] public int ParentId { get; } + public Guid? ParentKey { get; } + public bool RelateToOriginal { get; } } diff --git a/src/Umbraco.Core/Notifications/CopyingNotification.cs b/src/Umbraco.Core/Notifications/CopyingNotification.cs index 0992f9708b..2320d13f28 100644 --- a/src/Umbraco.Core/Notifications/CopyingNotification.cs +++ b/src/Umbraco.Core/Notifications/CopyingNotification.cs @@ -8,16 +8,26 @@ namespace Umbraco.Cms.Core.Notifications; public abstract class CopyingNotification : CancelableObjectNotification where T : class { - protected CopyingNotification(T original, T copy, int parentId, EventMessages messages) + protected CopyingNotification(T original, T copy, int parentId, Guid? parentKey, EventMessages messages) : base(original, messages) { Copy = copy; ParentId = parentId; + ParentKey = parentKey; + } + + [Obsolete("Please use constructor that takes a parent key, scheduled for removal in V15")] + protected CopyingNotification(T original, T copy, int parentId, EventMessages messages) + : this(original, copy, parentId, null, messages) + { } public T Original => Target; public T Copy { get; } + [Obsolete("Please use parent key instead, scheduled for removal in V15")] public int ParentId { get; } + + public Guid? ParentKey { get; } } diff --git a/src/Umbraco.Core/Notifications/MediaMovedToRecycleBinNotification.cs b/src/Umbraco.Core/Notifications/MediaMovedToRecycleBinNotification.cs index 78d771847b..c84fa73d50 100644 --- a/src/Umbraco.Core/Notifications/MediaMovedToRecycleBinNotification.cs +++ b/src/Umbraco.Core/Notifications/MediaMovedToRecycleBinNotification.cs @@ -8,12 +8,12 @@ namespace Umbraco.Cms.Core.Notifications; public sealed class MediaMovedToRecycleBinNotification : MovedToRecycleBinNotification { - public MediaMovedToRecycleBinNotification(MoveEventInfo target, EventMessages messages) + public MediaMovedToRecycleBinNotification(MoveToRecycleBinEventInfo target, EventMessages messages) : base(target, messages) { } - public MediaMovedToRecycleBinNotification(IEnumerable> target, EventMessages messages) + public MediaMovedToRecycleBinNotification(IEnumerable> target, EventMessages messages) : base(target, messages) { } diff --git a/src/Umbraco.Core/Notifications/MediaMovingToRecycleBinNotification.cs b/src/Umbraco.Core/Notifications/MediaMovingToRecycleBinNotification.cs index ee5618f9fb..a88484d150 100644 --- a/src/Umbraco.Core/Notifications/MediaMovingToRecycleBinNotification.cs +++ b/src/Umbraco.Core/Notifications/MediaMovingToRecycleBinNotification.cs @@ -8,12 +8,12 @@ namespace Umbraco.Cms.Core.Notifications; public sealed class MediaMovingToRecycleBinNotification : MovingToRecycleBinNotification { - public MediaMovingToRecycleBinNotification(MoveEventInfo target, EventMessages messages) + public MediaMovingToRecycleBinNotification(MoveToRecycleBinEventInfo target, EventMessages messages) : base(target, messages) { } - public MediaMovingToRecycleBinNotification(IEnumerable> target, EventMessages messages) + public MediaMovingToRecycleBinNotification(IEnumerable> target, EventMessages messages) : base(target, messages) { } diff --git a/src/Umbraco.Core/Notifications/MovedToRecycleBinNotification.cs b/src/Umbraco.Core/Notifications/MovedToRecycleBinNotification.cs index fddb0ab106..686dc407fc 100644 --- a/src/Umbraco.Core/Notifications/MovedToRecycleBinNotification.cs +++ b/src/Umbraco.Core/Notifications/MovedToRecycleBinNotification.cs @@ -5,17 +5,17 @@ using Umbraco.Cms.Core.Events; namespace Umbraco.Cms.Core.Notifications; -public abstract class MovedToRecycleBinNotification : ObjectNotification>> +public abstract class MovedToRecycleBinNotification : ObjectNotification>> { - protected MovedToRecycleBinNotification(MoveEventInfo target, EventMessages messages) + protected MovedToRecycleBinNotification(MoveToRecycleBinEventInfo target, EventMessages messages) : base(new[] { target }, messages) { } - protected MovedToRecycleBinNotification(IEnumerable> target, EventMessages messages) + protected MovedToRecycleBinNotification(IEnumerable> target, EventMessages messages) : base(target, messages) { } - public IEnumerable> MoveInfoCollection => Target; + public IEnumerable> MoveInfoCollection => Target; } diff --git a/src/Umbraco.Core/Notifications/MovingToRecycleBinNotification.cs b/src/Umbraco.Core/Notifications/MovingToRecycleBinNotification.cs index 37e486e3ff..38d6bbbc8c 100644 --- a/src/Umbraco.Core/Notifications/MovingToRecycleBinNotification.cs +++ b/src/Umbraco.Core/Notifications/MovingToRecycleBinNotification.cs @@ -5,17 +5,17 @@ using Umbraco.Cms.Core.Events; namespace Umbraco.Cms.Core.Notifications; -public abstract class MovingToRecycleBinNotification : CancelableObjectNotification>> +public abstract class MovingToRecycleBinNotification : CancelableObjectNotification>> { - protected MovingToRecycleBinNotification(MoveEventInfo target, EventMessages messages) + protected MovingToRecycleBinNotification(MoveToRecycleBinEventInfo target, EventMessages messages) : base(new[] { target }, messages) { } - protected MovingToRecycleBinNotification(IEnumerable> target, EventMessages messages) + protected MovingToRecycleBinNotification(IEnumerable> target, EventMessages messages) : base(target, messages) { } - public IEnumerable> MoveInfoCollection => Target; + public IEnumerable> MoveInfoCollection => Target; } diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index 2faab2922d..607e8dc7a8 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -2385,7 +2385,7 @@ public class ContentService : RepositoryService, IContentService var originalPath = content.Path; var moveEventInfo = - new MoveEventInfo(content, originalPath, Constants.System.RecycleBinContent); + new MoveToRecycleBinEventInfo(content, originalPath); var movingToRecycleBinNotification = new ContentMovingToRecycleBinNotification(moveEventInfo, eventMessages); @@ -2404,8 +2404,8 @@ public class ContentService : RepositoryService, IContentService scope.Notifications.Publish( new ContentTreeChangeNotification(content, TreeChangeTypes.RefreshBranch, eventMessages)); - MoveEventInfo[] moveInfo = moves - .Select(x => new MoveEventInfo(x.Item1, x.Item2, x.Item1.ParentId)) + MoveToRecycleBinEventInfo[] moveInfo = moves + .Select(x => new MoveToRecycleBinEventInfo(x.Item1, x.Item2)) .ToArray(); scope.Notifications.Publish( @@ -2458,6 +2458,7 @@ public class ContentService : RepositoryService, IContentService throw new InvalidOperationException("Parent does not exist or is trashed."); // causes rollback } + // FIXME: Use MoveEventInfo that also takes a parent key when implementing move with parentKey. var moveEventInfo = new MoveEventInfo(content, content.Path, parentId); var movingNotification = new ContentMovingNotification(moveEventInfo, eventMessages); @@ -2488,6 +2489,7 @@ public class ContentService : RepositoryService, IContentService new ContentTreeChangeNotification(content, TreeChangeTypes.RefreshBranch, eventMessages)); // changes + // FIXME: Use MoveEventInfo that also takes a parent key when implementing move with parentKey. MoveEventInfo[] moveInfo = moves .Select(x => new MoveEventInfo(x.Item1, x.Item2, x.Item1.ParentId)) .ToArray(); @@ -2643,6 +2645,7 @@ public class ContentService : RepositoryService, IContentService /// /// The to copy /// Id of the Content's new Parent + /// Key of the Content's new Parent /// Boolean indicating whether the copy should be related to the original /// A value indicating whether to recursively copy children. /// Optional Id of the User copying the Content @@ -2656,8 +2659,8 @@ public class ContentService : RepositoryService, IContentService using (ICoreScope scope = ScopeProvider.CreateCoreScope()) { - if (scope.Notifications.PublishCancelable( - new ContentCopyingNotification(content, copy, parentId, eventMessages))) + // FIXME: Pass parent key in constructor too when proper Copy method is implemented + if (scope.Notifications.PublishCancelable(new ContentCopyingNotification(content, copy, parentId, eventMessages))) { scope.Complete(); return null; @@ -2719,8 +2722,8 @@ public class ContentService : RepositoryService, IContentService IContent descendantCopy = descendant.DeepCloneWithResetIdentities(); descendantCopy.ParentId = parentId; - if (scope.Notifications.PublishCancelable( - new ContentCopyingNotification(descendant, descendantCopy, parentId, eventMessages))) + // FIXME: Pass parent key in constructor too when proper Copy method is implemented + if (scope.Notifications.PublishCancelable(new ContentCopyingNotification(descendant, descendantCopy, parentId, eventMessages))) { continue; } @@ -2751,6 +2754,7 @@ public class ContentService : RepositoryService, IContentService new ContentTreeChangeNotification(copy, TreeChangeTypes.RefreshBranch, eventMessages)); foreach (Tuple x in copies) { + // FIXME: Pass parent key in constructor too when proper Copy method is implemented scope.Notifications.Publish(new ContentCopiedNotification(x.Item1, x.Item2, parentId, relateToOriginal, eventMessages)); } @@ -3431,8 +3435,8 @@ public class ContentService : RepositoryService, IContentService changes.Add(new TreeChange(content, TreeChangeTypes.Remove)); } - MoveEventInfo[] moveInfos = moves - .Select(x => new MoveEventInfo(x.Item1, x.Item2, x.Item1.ParentId)) + MoveToRecycleBinEventInfo[] moveInfos = moves + .Select(x => new MoveToRecycleBinEventInfo(x.Item1, x.Item2)) .ToArray(); if (moveInfos.Length > 0) { diff --git a/src/Umbraco.Core/Services/DataTypeService.cs b/src/Umbraco.Core/Services/DataTypeService.cs index d143337c6f..a96f147cda 100644 --- a/src/Umbraco.Core/Services/DataTypeService.cs +++ b/src/Umbraco.Core/Services/DataTypeService.cs @@ -405,7 +405,7 @@ namespace Umbraco.Cms.Core.Services.Implement return Attempt.SucceedWithStatus(DataTypeOperationStatus.Success, toMove); } - var moveEventInfo = new MoveEventInfo(toMove, toMove.Path, parentId); + var moveEventInfo = new MoveEventInfo(toMove, toMove.Path, parentId, containerKey); var movingDataTypeNotification = new DataTypeMovingNotification(moveEventInfo, eventMessages); if (scope.Notifications.PublishCancelable(movingDataTypeNotification)) { diff --git a/src/Umbraco.Core/Services/DictionaryItemService.cs b/src/Umbraco.Core/Services/DictionaryItemService.cs index 1b6c0de6ae..319808eebc 100644 --- a/src/Umbraco.Core/Services/DictionaryItemService.cs +++ b/src/Umbraco.Core/Services/DictionaryItemService.cs @@ -212,7 +212,7 @@ internal sealed class DictionaryItemService : RepositoryService, IDictionaryItem dictionaryItem.ParentId = parentId; EventMessages eventMessages = EventMessagesFactory.Get(); - var moveEventInfo = new MoveEventInfo(dictionaryItem, string.Empty, parent?.Id ?? Constants.System.Root); + var moveEventInfo = new MoveEventInfo(dictionaryItem, string.Empty, parent?.Id ?? Constants.System.Root, parentId); var movingNotification = new DictionaryItemMovingNotification(moveEventInfo, eventMessages); if (await scope.Notifications.PublishCancelableAsync(movingNotification)) { diff --git a/src/Umbraco.Core/Services/MediaService.cs b/src/Umbraco.Core/Services/MediaService.cs index 325677407e..a9f81245d1 100644 --- a/src/Umbraco.Core/Services/MediaService.cs +++ b/src/Umbraco.Core/Services/MediaService.cs @@ -947,7 +947,7 @@ namespace Umbraco.Cms.Core.Services var originalPath = media.Path; - var moveEventInfo = new MoveEventInfo(media, originalPath, Constants.System.RecycleBinMedia); + var moveEventInfo = new MoveToRecycleBinEventInfo(media, originalPath); var movingToRecycleBinNotification = new MediaMovingToRecycleBinNotification(moveEventInfo, messages); if (scope.Notifications.PublishCancelable(movingToRecycleBinNotification)) @@ -959,7 +959,7 @@ namespace Umbraco.Cms.Core.Services PerformMoveLocked(media, Constants.System.RecycleBinMedia, null, userId, moves, true); scope.Notifications.Publish(new MediaTreeChangeNotification(media, TreeChangeTypes.RefreshBranch, messages)); - MoveEventInfo[] moveInfo = moves.Select(x => new MoveEventInfo(x.Item1, x.Item2, x.Item1.ParentId)).ToArray(); + MoveToRecycleBinEventInfo[] moveInfo = moves.Select(x => new MoveToRecycleBinEventInfo(x.Item1, x.Item2)).ToArray(); scope.Notifications.Publish(new MediaMovedToRecycleBinNotification(moveInfo, messages).WithStateFrom(movingToRecycleBinNotification)); Audit(AuditType.Move, userId, media.Id, "Move Media to recycle bin"); @@ -998,6 +998,7 @@ namespace Umbraco.Cms.Core.Services throw new InvalidOperationException("Parent does not exist or is trashed."); // causes rollback } + // FIXME: Use MoveEventInfo that also takes a parent key when implementing move with parentKey. var moveEventInfo = new MoveEventInfo(media, media.Path, parentId); var movingNotification = new MediaMovingNotification(moveEventInfo, messages); if (scope.Notifications.PublishCancelable(movingNotification)) @@ -1015,6 +1016,7 @@ namespace Umbraco.Cms.Core.Services scope.Notifications.Publish(new MediaTreeChangeNotification(media, TreeChangeTypes.RefreshBranch, messages)); MoveEventInfo[] moveInfo = moves //changes + // FIXME: Use MoveEventInfo that also takes a parent key when implementing move with parentKey. .Select(x => new MoveEventInfo(x.Item1, x.Item2, x.Item1.ParentId)) .ToArray(); scope.Notifications.Publish(new MediaMovedNotification(moveInfo, messages).WithStateFrom(movingNotification)); @@ -1322,7 +1324,7 @@ namespace Umbraco.Cms.Core.Services changes.Add(new TreeChange(media, TreeChangeTypes.Remove)); } - MoveEventInfo[] moveInfos = moves.Select(x => new MoveEventInfo(x.Item1, x.Item2, x.Item1.ParentId)) + MoveToRecycleBinEventInfo[] moveInfos = moves.Select(x => new MoveToRecycleBinEventInfo(x.Item1, x.Item2)) .ToArray(); if (moveInfos.Length > 0) { diff --git a/src/Umbraco.Infrastructure/Events/RelateOnTrashNotificationHandler.cs b/src/Umbraco.Infrastructure/Events/RelateOnTrashNotificationHandler.cs index 768c1bc7aa..c2a434dd54 100644 --- a/src/Umbraco.Infrastructure/Events/RelateOnTrashNotificationHandler.cs +++ b/src/Umbraco.Infrastructure/Events/RelateOnTrashNotificationHandler.cs @@ -71,7 +71,7 @@ public sealed class RelateOnTrashNotificationHandler : _relationService.Save(relationType); } - foreach (MoveEventInfo item in notification.MoveInfoCollection) + foreach (MoveToRecycleBinEventInfo item in notification.MoveInfoCollection) { IList originalPath = item.OriginalPath.ToDelimitedList(); var originalParentId = originalPath.Count > 2 @@ -132,7 +132,7 @@ public sealed class RelateOnTrashNotificationHandler : _relationService.Save(relationType); } - foreach (MoveEventInfo item in notification.MoveInfoCollection) + foreach (MoveToRecycleBinEventInfo item in notification.MoveInfoCollection) { IList originalPath = item.OriginalPath.ToDelimitedList(); var originalParentId = originalPath.Count > 2 diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs index 3e92a4ae7f..8b36a46224 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/ContentTypeRepositoryBase.cs @@ -80,6 +80,7 @@ internal abstract class ContentTypeRepositoryBase : EntityRepositoryBas public IEnumerable> Move(TEntity moving, EntityContainer? container) { var parentId = Constants.System.Root; + Guid? parentKey = Constants.System.RootKey; if (container != null) { // check path @@ -92,10 +93,11 @@ internal abstract class ContentTypeRepositoryBase : EntityRepositoryBas } parentId = container.Id; + parentKey = container.Key; } // track moved entities - var moveInfo = new List> { new(moving, moving.Path, parentId) }; + var moveInfo = new List> { new(moving, moving.Path, parentId, parentKey) }; // get the level delta (old pos to new pos) var levelDelta = container == null @@ -118,6 +120,7 @@ internal abstract class ContentTypeRepositoryBase : EntityRepositoryBas foreach (TEntity descendant in descendants.OrderBy(x => x.Level)) { + //FIXME: Use MoveEventInfo constructor that takes a parentKey when this method is refactored moveInfo.Add(new MoveEventInfo(descendant, descendant.Path, descendant.ParentId)); descendant.Path = paths[descendant.Id] = paths[descendant.ParentId] + "," + descendant.Id; diff --git a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DataTypeRepository.cs b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DataTypeRepository.cs index 9f9d685552..5d86055786 100644 --- a/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DataTypeRepository.cs +++ b/src/Umbraco.Infrastructure/Persistence/Repositories/Implement/DataTypeRepository.cs @@ -63,6 +63,7 @@ internal class DataTypeRepository : EntityRepositoryBase, IDataT } // used to track all the moved entities to be given to the event + // FIXME: Use constructor that takes parent key when this method is refactored var moveInfo = new List> { new(toMove, toMove.Path, parentId) }; var origPath = toMove.Path; @@ -85,6 +86,7 @@ internal class DataTypeRepository : EntityRepositoryBase, IDataT { foreach (IDataType descendant in descendants.OrderBy(x => x.Level)) { + // FIXME: Use constructor that takes parent key when this method is refactored moveInfo.Add(new MoveEventInfo(descendant, descendant.Path, descendant.ParentId)); descendant.ParentId = lastParent.Id; diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Events/MoveEventInfoTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Events/MoveEventInfoTests.cs new file mode 100644 index 0000000000..fc4c9c8081 --- /dev/null +++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Events/MoveEventInfoTests.cs @@ -0,0 +1,55 @@ +using NUnit.Framework; +using Umbraco.Cms.Core.Events; + +namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Events; + +public class MoveEventInfoTests +{ + [TestCase("", "path", false)] + [TestCase("entity", "", false)] + [TestCase("entity", "path", true)] + public void Can_Equate_Move_To_Recyclebin_Move_Event_Infos(string entity, string originalPath, bool expectedResult) + { + var recycleBinMoveEvent = new MoveToRecycleBinEventInfo(entity, originalPath); + var recycleBinMoveEventTwo = new MoveToRecycleBinEventInfo("entity", "path"); + + Assert.AreEqual(expectedResult, recycleBinMoveEvent.Equals(recycleBinMoveEventTwo)); + } + + [Test] + public void Can_Equate_Move_To_Recyclebin_Move_Event_Infos_All_Params_Null_Or_Empty() + { + var recycleBinMoveEvent = new MoveToRecycleBinEventInfo(string.Empty, string.Empty); + var recycleBinMoveEventTwo = new MoveToRecycleBinEventInfo(string.Empty, string.Empty); + + Assert.IsTrue(recycleBinMoveEvent.Equals(recycleBinMoveEventTwo)); + } + + [Test] + public void Can_Equate_Move_Event_Infos_Parent_Key_Null() + { + var moveEvent = new MoveEventInfo("entity", "path", 123, null); + var moveEventTwo = new MoveEventInfo("entity", "path", 123, null); + Assert.IsTrue(moveEvent.Equals(moveEventTwo)); + } + + [Test] + public void Can_Equate_Move_Event_Infos_All_Params_Null_Or_Empty() + { + var moveEvent = new MoveEventInfo(string.Empty, string.Empty, 0, null); + var moveEventTwo = new MoveEventInfo(string.Empty, string.Empty, 0, null); + Assert.IsTrue(moveEvent.Equals(moveEventTwo)); + } + + [TestCase(123, "entity", "", "063897F1-194A-4C42-B406-CA80DBC12968", false)] + [TestCase(123, "", "path", "063897F1-194A-4C42-B406-CA80DBC12968", false)] + [TestCase(12, "entity", "path", "063897F1-194A-4C42-B406-CA80DBC12968", false)] + [TestCase(123, "entity", "path", "C6D6EA3E-C2B0-483F-B772-2F4D8BBF5027", false)] + [TestCase(123, "entity", "path", "063897F1-194A-4C42-B406-CA80DBC12968", true)] + public void Can_Equate_Move_Event_Infos(int parentId, string entity, string originalPath, Guid parentKey, bool expectedResult) + { + var moveEvent = new MoveEventInfo(entity, originalPath, parentId, parentKey); + var moveEventTwo = new MoveEventInfo("entity", "path", 123, new Guid("063897F1-194A-4C42-B406-CA80DBC12968")); + Assert.AreEqual(expectedResult, moveEvent.Equals(moveEventTwo)); + } +}