V14: Copy and move endpoints for content and media types (#15553)
* Create new request models * Create new structural operation status * Handling of new structural operation status * New CopyAsync and MoveAsync * New endpoints * Update schema * Adding NotFound status * Adding BadRequest response type * Moving getbyid check to service * Fix signature and implement get by id check in service * Update OpenApi schema * Use PUT instead of POST in "move" controllers * Use PUT instead of POST in some more "move" controllers --------- Co-authored-by: kjac <kja@umbraco.dk>
This commit is contained in:
committed by
GitHub
parent
e291fae01e
commit
c5c24d36d9
@@ -754,6 +754,7 @@ public abstract class ContentTypeServiceBase<TRepository, TItem> : ContentTypeSe
|
||||
|
||||
#region Copy
|
||||
|
||||
[Obsolete("Please use CopyAsync. Will be removed in V15.")]
|
||||
public TItem Copy(TItem original, string alias, string name, int parentId = -1)
|
||||
{
|
||||
TItem? parent = null;
|
||||
@@ -768,6 +769,7 @@ public abstract class ContentTypeServiceBase<TRepository, TItem> : ContentTypeSe
|
||||
return Copy(original, alias, name, parent);
|
||||
}
|
||||
|
||||
[Obsolete("Please use CopyAsync. Will be removed in V15.")]
|
||||
public TItem Copy(TItem original, string alias, string name, TItem? parent)
|
||||
{
|
||||
if (original == null)
|
||||
@@ -822,6 +824,7 @@ public abstract class ContentTypeServiceBase<TRepository, TItem> : ContentTypeSe
|
||||
return clone;
|
||||
}
|
||||
|
||||
[Obsolete("Please use CopyAsync. Will be removed in V16.")]
|
||||
public Attempt<OperationResult<MoveOperationStatusType, TItem>?> Copy(TItem copying, int containerId)
|
||||
{
|
||||
EventMessages eventMessages = EventMessagesFactory.Get();
|
||||
@@ -894,10 +897,53 @@ public abstract class ContentTypeServiceBase<TRepository, TItem> : ContentTypeSe
|
||||
return OperationResult.Attempt.Succeed(MoveOperationStatusType.Success, eventMessages, copy);
|
||||
}
|
||||
|
||||
public async Task<Attempt<TItem?, ContentTypeStructureOperationStatus>> CopyAsync(Guid key, Guid? containerKey)
|
||||
{
|
||||
TItem? toCopy = await GetAsync(key);
|
||||
if (toCopy is null)
|
||||
{
|
||||
return Attempt.FailWithStatus(ContentTypeStructureOperationStatus.NotFound, toCopy);
|
||||
}
|
||||
|
||||
var containerId = GetContainerOrRootId(containerKey);
|
||||
|
||||
if (containerId is null)
|
||||
{
|
||||
return Attempt.FailWithStatus<TItem?, ContentTypeStructureOperationStatus>(ContentTypeStructureOperationStatus.ContainerNotFound, toCopy);
|
||||
}
|
||||
|
||||
// using obsolete method for version control while it still exists
|
||||
Attempt<OperationResult<MoveOperationStatusType, TItem>?> result = Copy(toCopy, containerId.Value);
|
||||
|
||||
return MapStatusTypeToAttempt(result.Result?.Entity, result.Result?.Result);
|
||||
}
|
||||
|
||||
private int? GetContainerOrRootId(Guid? containerKey)
|
||||
{
|
||||
if (containerKey is null)
|
||||
{
|
||||
return Constants.System.Root;
|
||||
}
|
||||
|
||||
EntityContainer? container = GetContainer(containerKey.Value);
|
||||
return container?.Id;
|
||||
}
|
||||
|
||||
private Attempt<TItem?, ContentTypeStructureOperationStatus> MapStatusTypeToAttempt(TItem? item, MoveOperationStatusType? resultStatus) =>
|
||||
resultStatus switch
|
||||
{
|
||||
MoveOperationStatusType.Success => Attempt.SucceedWithStatus(ContentTypeStructureOperationStatus.Success, item),
|
||||
MoveOperationStatusType.FailedParentNotFound => Attempt.FailWithStatus(ContentTypeStructureOperationStatus.ContainerNotFound, item),
|
||||
MoveOperationStatusType.FailedCancelledByEvent => Attempt.FailWithStatus(ContentTypeStructureOperationStatus.CancelledByNotification, item),
|
||||
MoveOperationStatusType.FailedNotAllowedByPath => Attempt.FailWithStatus(ContentTypeStructureOperationStatus.NotAllowedByPath, item),
|
||||
_ => throw new NotImplementedException($"{nameof(ContentTypeStructureOperationStatus)} does not map to a corresponding {nameof(MoveOperationStatusType)}")
|
||||
};
|
||||
|
||||
#endregion
|
||||
|
||||
#region Move
|
||||
|
||||
[Obsolete("Please use MoveAsync. Will be removed in V16.")]
|
||||
public Attempt<OperationResult<MoveOperationStatusType>?> Move(TItem moving, int containerId)
|
||||
{
|
||||
EventMessages eventMessages = EventMessagesFactory.Get();
|
||||
@@ -950,6 +996,27 @@ public abstract class ContentTypeServiceBase<TRepository, TItem> : ContentTypeSe
|
||||
return OperationResult.Attempt.Succeed(MoveOperationStatusType.Success, eventMessages);
|
||||
}
|
||||
|
||||
public async Task<Attempt<TItem?, ContentTypeStructureOperationStatus>> MoveAsync(Guid key, Guid? containerKey)
|
||||
{
|
||||
TItem? toMove = await GetAsync(key);
|
||||
if (toMove is null)
|
||||
{
|
||||
return Attempt.FailWithStatus(ContentTypeStructureOperationStatus.NotFound, toMove);
|
||||
}
|
||||
|
||||
var containerId = GetContainerOrRootId(containerKey);
|
||||
|
||||
if (containerId is null)
|
||||
{
|
||||
return Attempt.FailWithStatus<TItem?, ContentTypeStructureOperationStatus>(ContentTypeStructureOperationStatus.ContainerNotFound, toMove);
|
||||
}
|
||||
|
||||
// using obsolete method for version control while it still exists
|
||||
Attempt<OperationResult<MoveOperationStatusType>?> result = Move(toMove, containerId.Value);
|
||||
|
||||
return MapStatusTypeToAttempt(toMove, result.Result?.Result);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Containers
|
||||
|
||||
@@ -124,11 +124,19 @@ public interface IContentTypeBaseService<TItem> : IContentTypeBaseService, IServ
|
||||
|
||||
Attempt<OperationResult<OperationResultType, EntityContainer>?> RenameContainer(int id, string name, int userId = Constants.Security.SuperUserId);
|
||||
|
||||
[Obsolete("Please use MoveAsync. Will be removed in V16.")]
|
||||
Attempt<OperationResult<MoveOperationStatusType>?> Move(TItem moving, int containerId);
|
||||
|
||||
[Obsolete("Please use CopyAsync. Will be removed in V16.")]
|
||||
Attempt<OperationResult<MoveOperationStatusType, TItem>?> Copy(TItem copying, int containerId);
|
||||
|
||||
[Obsolete("Please use CopyAsync. Will be removed in V15.")]
|
||||
TItem Copy(TItem original, string alias, string name, int parentId = -1);
|
||||
|
||||
[Obsolete("Please use CopyAsync. Will be removed in V15.")]
|
||||
TItem Copy(TItem original, string alias, string name, TItem parent);
|
||||
|
||||
Task<Attempt<TItem?, ContentTypeStructureOperationStatus>> CopyAsync(Guid key, Guid? containerKey);
|
||||
|
||||
Task<Attempt<TItem?, ContentTypeStructureOperationStatus>> MoveAsync(Guid key, Guid? containerKey);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
namespace Umbraco.Cms.Core.Services.OperationStatus;
|
||||
|
||||
public enum ContentTypeStructureOperationStatus
|
||||
{
|
||||
Success,
|
||||
CancelledByNotification,
|
||||
ContainerNotFound,
|
||||
NotAllowedByPath,
|
||||
NotFound
|
||||
}
|
||||
Reference in New Issue
Block a user