Management API: Return not found from request for content references when entity does not exist (closes #20997) (#20999)
* Return not found when request for content references when entity does not exist.
* Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Move check for entity existence from controller to the service.
* Update OpenApi.json.
* Apply suggestions from code review
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Addressed points raised in code review.
* Update OpenApi.json
* Resolved breaking changes.
---------
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
(cherry picked from commit da94e0953b)
This commit is contained in:
@@ -1,7 +1,5 @@
|
|||||||
using Microsoft.AspNetCore.Http;
|
using Microsoft.AspNetCore.Http;
|
||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Umbraco.Cms.Api.Management.ViewModels.Content;
|
|
||||||
using Umbraco.Cms.Core.Mapping;
|
|
||||||
using Umbraco.Cms.Core.Models.ContentEditing;
|
using Umbraco.Cms.Core.Models.ContentEditing;
|
||||||
using Umbraco.Cms.Core.Models.ContentEditing.Validation;
|
using Umbraco.Cms.Core.Models.ContentEditing.Validation;
|
||||||
using Umbraco.Cms.Core.PropertyEditors.Validation;
|
using Umbraco.Cms.Core.PropertyEditors.Validation;
|
||||||
@@ -12,7 +10,6 @@ namespace Umbraco.Cms.Api.Management.Controllers.Content;
|
|||||||
|
|
||||||
public abstract class ContentControllerBase : ManagementApiControllerBase
|
public abstract class ContentControllerBase : ManagementApiControllerBase
|
||||||
{
|
{
|
||||||
|
|
||||||
protected IActionResult ContentEditingOperationStatusResult(ContentEditingOperationStatus status)
|
protected IActionResult ContentEditingOperationStatusResult(ContentEditingOperationStatus status)
|
||||||
=> OperationStatusResult(status, problemDetailsBuilder => status switch
|
=> OperationStatusResult(status, problemDetailsBuilder => status switch
|
||||||
{
|
{
|
||||||
@@ -98,6 +95,17 @@ public abstract class ContentControllerBase : ManagementApiControllerBase
|
|||||||
.Build()),
|
.Build()),
|
||||||
});
|
});
|
||||||
|
|
||||||
|
protected IActionResult GetReferencesOperationStatusResult(GetReferencesOperationStatus status)
|
||||||
|
=> OperationStatusResult(status, problemDetailsBuilder => status switch
|
||||||
|
{
|
||||||
|
GetReferencesOperationStatus.ContentNotFound => NotFound(problemDetailsBuilder
|
||||||
|
.WithTitle("The requested content could not be found")
|
||||||
|
.Build()),
|
||||||
|
_ => StatusCode(StatusCodes.Status500InternalServerError, problemDetailsBuilder
|
||||||
|
.WithTitle("Unknown get references operation status.")
|
||||||
|
.Build()),
|
||||||
|
});
|
||||||
|
|
||||||
protected IActionResult ContentEditingOperationStatusResult<TContentModelBase, TValueModel, TVariantModel>(
|
protected IActionResult ContentEditingOperationStatusResult<TContentModelBase, TValueModel, TVariantModel>(
|
||||||
ContentEditingOperationStatus status,
|
ContentEditingOperationStatus status,
|
||||||
TContentModelBase requestModel,
|
TContentModelBase requestModel,
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||||
using Umbraco.Cms.Api.Management.Factories;
|
using Umbraco.Cms.Api.Management.Factories;
|
||||||
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
|
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
|
||||||
|
using Umbraco.Cms.Core;
|
||||||
using Umbraco.Cms.Core.Models;
|
using Umbraco.Cms.Core.Models;
|
||||||
using Umbraco.Cms.Core.Services;
|
using Umbraco.Cms.Core.Services;
|
||||||
|
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||||
|
|
||||||
namespace Umbraco.Cms.Api.Management.Controllers.Document.References;
|
namespace Umbraco.Cms.Api.Management.Controllers.Document.References;
|
||||||
|
|
||||||
@@ -15,22 +17,16 @@ public class ReferencedByDocumentController : DocumentControllerBase
|
|||||||
private readonly ITrackedReferencesService _trackedReferencesService;
|
private readonly ITrackedReferencesService _trackedReferencesService;
|
||||||
private readonly IRelationTypePresentationFactory _relationTypePresentationFactory;
|
private readonly IRelationTypePresentationFactory _relationTypePresentationFactory;
|
||||||
|
|
||||||
public ReferencedByDocumentController(ITrackedReferencesService trackedReferencesService, IRelationTypePresentationFactory relationTypePresentationFactory)
|
public ReferencedByDocumentController(
|
||||||
|
ITrackedReferencesService trackedReferencesService,
|
||||||
|
IRelationTypePresentationFactory relationTypePresentationFactory)
|
||||||
{
|
{
|
||||||
_trackedReferencesService = trackedReferencesService;
|
_trackedReferencesService = trackedReferencesService;
|
||||||
_relationTypePresentationFactory = relationTypePresentationFactory;
|
_relationTypePresentationFactory = relationTypePresentationFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
[Obsolete("Use the ReferencedBy2 action method instead. Scheduled for removal in Umbraco 19, when ReferencedBy2 will be renamed back to ReferencedBy.")]
|
||||||
/// Gets a paged list of tracked references for the current item, so you can see where an item is being used.
|
[NonAction]
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Used by info tabs on content, media etc. and for the delete and unpublish of single items.
|
|
||||||
/// This is basically finding parents of relations.
|
|
||||||
/// </remarks>
|
|
||||||
[HttpGet("{id:guid}/referenced-by")]
|
|
||||||
[MapToApiVersion("1.0")]
|
|
||||||
[ProducesResponseType(typeof(PagedViewModel<IReferenceResponseModel>), StatusCodes.Status200OK)]
|
|
||||||
public async Task<ActionResult<PagedViewModel<IReferenceResponseModel>>> ReferencedBy(
|
public async Task<ActionResult<PagedViewModel<IReferenceResponseModel>>> ReferencedBy(
|
||||||
CancellationToken cancellationToken,
|
CancellationToken cancellationToken,
|
||||||
Guid id,
|
Guid id,
|
||||||
@@ -47,4 +43,37 @@ public class ReferencedByDocumentController : DocumentControllerBase
|
|||||||
|
|
||||||
return pagedViewModel;
|
return pagedViewModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a paged list of tracked references for the current item, so you can see where an item is being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Used by info tabs on content, media etc. and for the delete and unpublish of single items.
|
||||||
|
/// This is basically finding parents of relations.
|
||||||
|
/// </remarks>
|
||||||
|
[HttpGet("{id:guid}/referenced-by")]
|
||||||
|
[MapToApiVersion("1.0")]
|
||||||
|
[ProducesResponseType(typeof(PagedViewModel<IReferenceResponseModel>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> ReferencedBy2(
|
||||||
|
CancellationToken cancellationToken,
|
||||||
|
Guid id,
|
||||||
|
int skip = 0,
|
||||||
|
int take = 20)
|
||||||
|
{
|
||||||
|
Attempt<PagedModel<RelationItemModel>, GetReferencesOperationStatus> relationItemsAttempt = await _trackedReferencesService.GetPagedRelationsForItemAsync(id, UmbracoObjectTypes.Document, skip, take, true);
|
||||||
|
|
||||||
|
if (relationItemsAttempt.Success is false)
|
||||||
|
{
|
||||||
|
return GetReferencesOperationStatusResult(relationItemsAttempt.Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
var pagedViewModel = new PagedViewModel<IReferenceResponseModel>
|
||||||
|
{
|
||||||
|
Total = relationItemsAttempt.Result.Total,
|
||||||
|
Items = await _relationTypePresentationFactory.CreateReferenceResponseModelsAsync(relationItemsAttempt.Result.Items),
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(pagedViewModel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ using Microsoft.AspNetCore.Http;
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||||
using Umbraco.Cms.Api.Management.ViewModels;
|
using Umbraco.Cms.Api.Management.ViewModels;
|
||||||
|
using Umbraco.Cms.Core;
|
||||||
using Umbraco.Cms.Core.Mapping;
|
using Umbraco.Cms.Core.Mapping;
|
||||||
using Umbraco.Cms.Core.Models;
|
using Umbraco.Cms.Core.Models;
|
||||||
using Umbraco.Cms.Core.Services;
|
using Umbraco.Cms.Core.Services;
|
||||||
|
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||||
|
|
||||||
namespace Umbraco.Cms.Api.Management.Controllers.Document.References;
|
namespace Umbraco.Cms.Api.Management.Controllers.Document.References;
|
||||||
|
|
||||||
@@ -15,12 +17,32 @@ public class ReferencedDescendantsDocumentController : DocumentControllerBase
|
|||||||
private readonly ITrackedReferencesService _trackedReferencesSkipTakeService;
|
private readonly ITrackedReferencesService _trackedReferencesSkipTakeService;
|
||||||
private readonly IUmbracoMapper _umbracoMapper;
|
private readonly IUmbracoMapper _umbracoMapper;
|
||||||
|
|
||||||
public ReferencedDescendantsDocumentController(ITrackedReferencesService trackedReferencesSkipTakeService, IUmbracoMapper umbracoMapper)
|
public ReferencedDescendantsDocumentController(
|
||||||
|
ITrackedReferencesService trackedReferencesSkipTakeService,
|
||||||
|
IUmbracoMapper umbracoMapper)
|
||||||
{
|
{
|
||||||
_trackedReferencesSkipTakeService = trackedReferencesSkipTakeService;
|
_trackedReferencesSkipTakeService = trackedReferencesSkipTakeService;
|
||||||
_umbracoMapper = umbracoMapper;
|
_umbracoMapper = umbracoMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete("Use the ReferencedDescendants2 action method instead. Scheduled for removal in Umbraco 19, when ReferencedDescendants2 will be renamed back to ReferencedDescendants.")]
|
||||||
|
[NonAction]
|
||||||
|
public async Task<ActionResult<PagedViewModel<ReferenceByIdModel>>> ReferencedDescendants(
|
||||||
|
CancellationToken cancellationToken,
|
||||||
|
Guid id,
|
||||||
|
int skip = 0,
|
||||||
|
int take = 20)
|
||||||
|
{
|
||||||
|
PagedModel<RelationItemModel> relationItems = await _trackedReferencesSkipTakeService.GetPagedDescendantsInReferencesAsync(id, skip, take, true);
|
||||||
|
var pagedViewModel = new PagedViewModel<ReferenceByIdModel>
|
||||||
|
{
|
||||||
|
Total = relationItems.Total,
|
||||||
|
Items = _umbracoMapper.MapEnumerable<RelationItemModel, ReferenceByIdModel>(relationItems.Items),
|
||||||
|
};
|
||||||
|
|
||||||
|
return pagedViewModel;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a paged list of the descendant nodes of the current item used in any kind of relation.
|
/// Gets a paged list of the descendant nodes of the current item used in any kind of relation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -32,19 +54,26 @@ public class ReferencedDescendantsDocumentController : DocumentControllerBase
|
|||||||
[HttpGet("{id:guid}/referenced-descendants")]
|
[HttpGet("{id:guid}/referenced-descendants")]
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[ProducesResponseType(typeof(PagedViewModel<ReferenceByIdModel>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(PagedViewModel<ReferenceByIdModel>), StatusCodes.Status200OK)]
|
||||||
public async Task<ActionResult<PagedViewModel<ReferenceByIdModel>>> ReferencedDescendants(
|
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> ReferencedDescendants2(
|
||||||
CancellationToken cancellationToken,
|
CancellationToken cancellationToken,
|
||||||
Guid id,
|
Guid id,
|
||||||
int skip = 0,
|
int skip = 0,
|
||||||
int take = 20)
|
int take = 20)
|
||||||
{
|
{
|
||||||
PagedModel<RelationItemModel> relationItems = await _trackedReferencesSkipTakeService.GetPagedDescendantsInReferencesAsync(id, skip, take, true);
|
Attempt<PagedModel<RelationItemModel>, GetReferencesOperationStatus> relationItemsAttempt = await _trackedReferencesSkipTakeService.GetPagedDescendantsInReferencesAsync(id, UmbracoObjectTypes.Document, skip, take, true);
|
||||||
|
|
||||||
|
if (relationItemsAttempt.Success is false)
|
||||||
|
{
|
||||||
|
return GetReferencesOperationStatusResult(relationItemsAttempt.Status);
|
||||||
|
}
|
||||||
|
|
||||||
var pagedViewModel = new PagedViewModel<ReferenceByIdModel>
|
var pagedViewModel = new PagedViewModel<ReferenceByIdModel>
|
||||||
{
|
{
|
||||||
Total = relationItems.Total,
|
Total = relationItemsAttempt.Result.Total,
|
||||||
Items = _umbracoMapper.MapEnumerable<RelationItemModel, ReferenceByIdModel>(relationItems.Items),
|
Items = _umbracoMapper.MapEnumerable<RelationItemModel, ReferenceByIdModel>(relationItemsAttempt.Result.Items),
|
||||||
};
|
};
|
||||||
|
|
||||||
return pagedViewModel;
|
return Ok(pagedViewModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||||
using Umbraco.Cms.Api.Management.Factories;
|
using Umbraco.Cms.Api.Management.Factories;
|
||||||
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
|
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
|
||||||
|
using Umbraco.Cms.Core;
|
||||||
using Umbraco.Cms.Core.Models;
|
using Umbraco.Cms.Core.Models;
|
||||||
using Umbraco.Cms.Core.Services;
|
using Umbraco.Cms.Core.Services;
|
||||||
|
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||||
|
|
||||||
namespace Umbraco.Cms.Api.Management.Controllers.Media.References;
|
namespace Umbraco.Cms.Api.Management.Controllers.Media.References;
|
||||||
|
|
||||||
@@ -15,22 +17,16 @@ public class ReferencedByMediaController : MediaControllerBase
|
|||||||
private readonly ITrackedReferencesService _trackedReferencesService;
|
private readonly ITrackedReferencesService _trackedReferencesService;
|
||||||
private readonly IRelationTypePresentationFactory _relationTypePresentationFactory;
|
private readonly IRelationTypePresentationFactory _relationTypePresentationFactory;
|
||||||
|
|
||||||
public ReferencedByMediaController(ITrackedReferencesService trackedReferencesService, IRelationTypePresentationFactory relationTypePresentationFactory)
|
public ReferencedByMediaController(
|
||||||
|
ITrackedReferencesService trackedReferencesService,
|
||||||
|
IRelationTypePresentationFactory relationTypePresentationFactory)
|
||||||
{
|
{
|
||||||
_trackedReferencesService = trackedReferencesService;
|
_trackedReferencesService = trackedReferencesService;
|
||||||
_relationTypePresentationFactory = relationTypePresentationFactory;
|
_relationTypePresentationFactory = relationTypePresentationFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
[Obsolete("Use the ReferencedBy2 action method instead. Scheduled for removal in Umbraco 19, when ReferencedBy2 will be renamed back to ReferencedBy.")]
|
||||||
/// Gets a page list of tracked references for the current item, so you can see where an item is being used.
|
[NonAction]
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Used by info tabs on content, media etc. and for the delete and unpublish of single items.
|
|
||||||
/// This is basically finding parents of relations.
|
|
||||||
/// </remarks>
|
|
||||||
[HttpGet("{id:guid}/referenced-by")]
|
|
||||||
[MapToApiVersion("1.0")]
|
|
||||||
[ProducesResponseType(typeof(PagedViewModel<IReferenceResponseModel>), StatusCodes.Status200OK)]
|
|
||||||
public async Task<ActionResult<PagedViewModel<IReferenceResponseModel>>> ReferencedBy(
|
public async Task<ActionResult<PagedViewModel<IReferenceResponseModel>>> ReferencedBy(
|
||||||
CancellationToken cancellationToken,
|
CancellationToken cancellationToken,
|
||||||
Guid id,
|
Guid id,
|
||||||
@@ -47,4 +43,37 @@ public class ReferencedByMediaController : MediaControllerBase
|
|||||||
|
|
||||||
return pagedViewModel;
|
return pagedViewModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a page list of tracked references for the current item, so you can see where an item is being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Used by info tabs on content, media etc. and for the delete and unpublish of single items.
|
||||||
|
/// This is basically finding parents of relations.
|
||||||
|
/// </remarks>
|
||||||
|
[HttpGet("{id:guid}/referenced-by")]
|
||||||
|
[MapToApiVersion("1.0")]
|
||||||
|
[ProducesResponseType(typeof(PagedViewModel<IReferenceResponseModel>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> ReferencedBy2(
|
||||||
|
CancellationToken cancellationToken,
|
||||||
|
Guid id,
|
||||||
|
int skip = 0,
|
||||||
|
int take = 20)
|
||||||
|
{
|
||||||
|
Attempt<PagedModel<RelationItemModel>, GetReferencesOperationStatus> relationItemsAttempt = await _trackedReferencesService.GetPagedRelationsForItemAsync(id, UmbracoObjectTypes.Media, skip, take, true);
|
||||||
|
|
||||||
|
if (relationItemsAttempt.Success is false)
|
||||||
|
{
|
||||||
|
return GetReferencesOperationStatusResult(relationItemsAttempt.Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
var pagedViewModel = new PagedViewModel<IReferenceResponseModel>
|
||||||
|
{
|
||||||
|
Total = relationItemsAttempt.Result.Total,
|
||||||
|
Items = await _relationTypePresentationFactory.CreateReferenceResponseModelsAsync(relationItemsAttempt.Result.Items),
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(pagedViewModel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ using Microsoft.AspNetCore.Http;
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||||
using Umbraco.Cms.Api.Management.ViewModels;
|
using Umbraco.Cms.Api.Management.ViewModels;
|
||||||
|
using Umbraco.Cms.Core;
|
||||||
using Umbraco.Cms.Core.Mapping;
|
using Umbraco.Cms.Core.Mapping;
|
||||||
using Umbraco.Cms.Core.Models;
|
using Umbraco.Cms.Core.Models;
|
||||||
using Umbraco.Cms.Core.Services;
|
using Umbraco.Cms.Core.Services;
|
||||||
|
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||||
|
|
||||||
namespace Umbraco.Cms.Api.Management.Controllers.Media.References;
|
namespace Umbraco.Cms.Api.Management.Controllers.Media.References;
|
||||||
|
|
||||||
@@ -14,13 +16,32 @@ public class ReferencedDescendantsMediaController : MediaControllerBase
|
|||||||
{
|
{
|
||||||
private readonly ITrackedReferencesService _trackedReferencesSkipTakeService;
|
private readonly ITrackedReferencesService _trackedReferencesSkipTakeService;
|
||||||
private readonly IUmbracoMapper _umbracoMapper;
|
private readonly IUmbracoMapper _umbracoMapper;
|
||||||
|
public ReferencedDescendantsMediaController(
|
||||||
public ReferencedDescendantsMediaController(ITrackedReferencesService trackedReferencesSkipTakeService, IUmbracoMapper umbracoMapper)
|
ITrackedReferencesService trackedReferencesSkipTakeService,
|
||||||
|
IUmbracoMapper umbracoMapper)
|
||||||
{
|
{
|
||||||
_trackedReferencesSkipTakeService = trackedReferencesSkipTakeService;
|
_trackedReferencesSkipTakeService = trackedReferencesSkipTakeService;
|
||||||
_umbracoMapper = umbracoMapper;
|
_umbracoMapper = umbracoMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete("Use the ReferencedDescendants2 action method instead. Scheduled for removal in Umbraco 19, when ReferencedDescendants2 will be renamed back to ReferencedDescendants.")]
|
||||||
|
[NonAction]
|
||||||
|
public async Task<ActionResult<PagedViewModel<ReferenceByIdModel>>> ReferencedDescendants(
|
||||||
|
CancellationToken cancellationToken,
|
||||||
|
Guid id,
|
||||||
|
int skip = 0,
|
||||||
|
int take = 20)
|
||||||
|
{
|
||||||
|
PagedModel<RelationItemModel> relationItems = await _trackedReferencesSkipTakeService.GetPagedDescendantsInReferencesAsync(id, skip, take, true);
|
||||||
|
var pagedViewModel = new PagedViewModel<ReferenceByIdModel>
|
||||||
|
{
|
||||||
|
Total = relationItems.Total,
|
||||||
|
Items = _umbracoMapper.MapEnumerable<RelationItemModel, ReferenceByIdModel>(relationItems.Items),
|
||||||
|
};
|
||||||
|
|
||||||
|
return pagedViewModel;
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a page list of the child nodes of the current item used in any kind of relation.
|
/// Gets a page list of the child nodes of the current item used in any kind of relation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -32,19 +53,26 @@ public class ReferencedDescendantsMediaController : MediaControllerBase
|
|||||||
[HttpGet("{id:guid}/referenced-descendants")]
|
[HttpGet("{id:guid}/referenced-descendants")]
|
||||||
[MapToApiVersion("1.0")]
|
[MapToApiVersion("1.0")]
|
||||||
[ProducesResponseType(typeof(PagedViewModel<ReferenceByIdModel>), StatusCodes.Status200OK)]
|
[ProducesResponseType(typeof(PagedViewModel<ReferenceByIdModel>), StatusCodes.Status200OK)]
|
||||||
public async Task<ActionResult<PagedViewModel<ReferenceByIdModel>>> ReferencedDescendants(
|
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> ReferencedDescendants2(
|
||||||
CancellationToken cancellationToken,
|
CancellationToken cancellationToken,
|
||||||
Guid id,
|
Guid id,
|
||||||
int skip = 0,
|
int skip = 0,
|
||||||
int take = 20)
|
int take = 20)
|
||||||
{
|
{
|
||||||
PagedModel<RelationItemModel> relationItems = await _trackedReferencesSkipTakeService.GetPagedDescendantsInReferencesAsync(id, skip, take, true);
|
Attempt<PagedModel<RelationItemModel>, GetReferencesOperationStatus> relationItemsAttempt = await _trackedReferencesSkipTakeService.GetPagedDescendantsInReferencesAsync(id, UmbracoObjectTypes.Media, skip, take, true);
|
||||||
|
|
||||||
|
if (relationItemsAttempt.Success is false)
|
||||||
|
{
|
||||||
|
return GetReferencesOperationStatusResult(relationItemsAttempt.Status);
|
||||||
|
}
|
||||||
|
|
||||||
var pagedViewModel = new PagedViewModel<ReferenceByIdModel>
|
var pagedViewModel = new PagedViewModel<ReferenceByIdModel>
|
||||||
{
|
{
|
||||||
Total = relationItems.Total,
|
Total = relationItemsAttempt.Result.Total,
|
||||||
Items = _umbracoMapper.MapEnumerable<RelationItemModel, ReferenceByIdModel>(relationItems.Items),
|
Items = _umbracoMapper.MapEnumerable<RelationItemModel, ReferenceByIdModel>(relationItemsAttempt.Result.Items),
|
||||||
};
|
};
|
||||||
|
|
||||||
return pagedViewModel;
|
return Ok(pagedViewModel);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,8 +4,10 @@ using Microsoft.AspNetCore.Mvc;
|
|||||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||||
using Umbraco.Cms.Api.Management.Factories;
|
using Umbraco.Cms.Api.Management.Factories;
|
||||||
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
|
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
|
||||||
|
using Umbraco.Cms.Core;
|
||||||
using Umbraco.Cms.Core.Models;
|
using Umbraco.Cms.Core.Models;
|
||||||
using Umbraco.Cms.Core.Services;
|
using Umbraco.Cms.Core.Services;
|
||||||
|
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||||
|
|
||||||
namespace Umbraco.Cms.Api.Management.Controllers.Member.References;
|
namespace Umbraco.Cms.Api.Management.Controllers.Member.References;
|
||||||
|
|
||||||
@@ -15,22 +17,16 @@ public class ReferencedByMemberController : MemberControllerBase
|
|||||||
private readonly ITrackedReferencesService _trackedReferencesService;
|
private readonly ITrackedReferencesService _trackedReferencesService;
|
||||||
private readonly IRelationTypePresentationFactory _relationTypePresentationFactory;
|
private readonly IRelationTypePresentationFactory _relationTypePresentationFactory;
|
||||||
|
|
||||||
public ReferencedByMemberController(ITrackedReferencesService trackedReferencesService, IRelationTypePresentationFactory relationTypePresentationFactory)
|
public ReferencedByMemberController(
|
||||||
|
ITrackedReferencesService trackedReferencesService,
|
||||||
|
IRelationTypePresentationFactory relationTypePresentationFactory)
|
||||||
{
|
{
|
||||||
_trackedReferencesService = trackedReferencesService;
|
_trackedReferencesService = trackedReferencesService;
|
||||||
_relationTypePresentationFactory = relationTypePresentationFactory;
|
_relationTypePresentationFactory = relationTypePresentationFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
[Obsolete("Use the ReferencedBy2 action method instead. Scheduled for removal in Umbraco 19, when ReferencedBy2 will be renamed back to ReferencedBy.")]
|
||||||
/// Gets a page list of tracked references for the current item, so you can see where an item is being used.
|
[NonAction]
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Used by info tabs on content, media etc. and for the delete and unpublish of single items.
|
|
||||||
/// This is basically finding parents of relations.
|
|
||||||
/// </remarks>
|
|
||||||
[HttpGet("{id:guid}/referenced-by")]
|
|
||||||
[MapToApiVersion("1.0")]
|
|
||||||
[ProducesResponseType(typeof(PagedViewModel<IReferenceResponseModel>), StatusCodes.Status200OK)]
|
|
||||||
public async Task<ActionResult<PagedViewModel<IReferenceResponseModel>>> ReferencedBy(
|
public async Task<ActionResult<PagedViewModel<IReferenceResponseModel>>> ReferencedBy(
|
||||||
CancellationToken cancellationToken,
|
CancellationToken cancellationToken,
|
||||||
Guid id,
|
Guid id,
|
||||||
@@ -47,4 +43,37 @@ public class ReferencedByMemberController : MemberControllerBase
|
|||||||
|
|
||||||
return pagedViewModel;
|
return pagedViewModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a page list of tracked references for the current item, so you can see where an item is being used.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Used by info tabs on content, media etc. and for the delete and unpublish of single items.
|
||||||
|
/// This is basically finding parents of relations.
|
||||||
|
/// </remarks>
|
||||||
|
[HttpGet("{id:guid}/referenced-by")]
|
||||||
|
[MapToApiVersion("1.0")]
|
||||||
|
[ProducesResponseType(typeof(PagedViewModel<IReferenceResponseModel>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> ReferencedBy2(
|
||||||
|
CancellationToken cancellationToken,
|
||||||
|
Guid id,
|
||||||
|
int skip = 0,
|
||||||
|
int take = 20)
|
||||||
|
{
|
||||||
|
Attempt<PagedModel<RelationItemModel>, GetReferencesOperationStatus> relationItemsAttempt = await _trackedReferencesService.GetPagedRelationsForItemAsync(id, UmbracoObjectTypes.Member, skip, take, true);
|
||||||
|
|
||||||
|
if (relationItemsAttempt.Success is false)
|
||||||
|
{
|
||||||
|
return GetReferencesOperationStatusResult(relationItemsAttempt.Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
var pagedViewModel = new PagedViewModel<IReferenceResponseModel>
|
||||||
|
{
|
||||||
|
Total = relationItemsAttempt.Result.Total,
|
||||||
|
Items = await _relationTypePresentationFactory.CreateReferenceResponseModelsAsync(relationItemsAttempt.Result.Items),
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(pagedViewModel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,9 +3,11 @@ using Microsoft.AspNetCore.Http;
|
|||||||
using Microsoft.AspNetCore.Mvc;
|
using Microsoft.AspNetCore.Mvc;
|
||||||
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
|
||||||
using Umbraco.Cms.Api.Management.ViewModels;
|
using Umbraco.Cms.Api.Management.ViewModels;
|
||||||
|
using Umbraco.Cms.Core;
|
||||||
using Umbraco.Cms.Core.Mapping;
|
using Umbraco.Cms.Core.Mapping;
|
||||||
using Umbraco.Cms.Core.Models;
|
using Umbraco.Cms.Core.Models;
|
||||||
using Umbraco.Cms.Core.Services;
|
using Umbraco.Cms.Core.Services;
|
||||||
|
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||||
|
|
||||||
namespace Umbraco.Cms.Api.Management.Controllers.Member.References;
|
namespace Umbraco.Cms.Api.Management.Controllers.Member.References;
|
||||||
|
|
||||||
@@ -15,23 +17,16 @@ public class ReferencedDescendantsMemberController : MemberControllerBase
|
|||||||
private readonly ITrackedReferencesService _trackedReferencesSkipTakeService;
|
private readonly ITrackedReferencesService _trackedReferencesSkipTakeService;
|
||||||
private readonly IUmbracoMapper _umbracoMapper;
|
private readonly IUmbracoMapper _umbracoMapper;
|
||||||
|
|
||||||
public ReferencedDescendantsMemberController(ITrackedReferencesService trackedReferencesSkipTakeService, IUmbracoMapper umbracoMapper)
|
public ReferencedDescendantsMemberController(
|
||||||
|
ITrackedReferencesService trackedReferencesSkipTakeService,
|
||||||
|
IUmbracoMapper umbracoMapper)
|
||||||
{
|
{
|
||||||
_trackedReferencesSkipTakeService = trackedReferencesSkipTakeService;
|
_trackedReferencesSkipTakeService = trackedReferencesSkipTakeService;
|
||||||
_umbracoMapper = umbracoMapper;
|
_umbracoMapper = umbracoMapper;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
[Obsolete("Use the ReferencedDescendants2 action method instead. Scheduled for removal in Umbraco 19, when ReferencedDescendants2 will be renamed back to ReferencedDescendants.")]
|
||||||
/// Gets a page list of the child nodes of the current item used in any kind of relation.
|
[NonAction]
|
||||||
/// </summary>
|
|
||||||
/// <remarks>
|
|
||||||
/// Used when deleting and unpublishing a single item to check if this item has any descending items that are in any
|
|
||||||
/// kind of relation.
|
|
||||||
/// This is basically finding the descending items which are children in relations.
|
|
||||||
/// </remarks>
|
|
||||||
[HttpGet("{id:guid}/referenced-descendants")]
|
|
||||||
[MapToApiVersion("1.0")]
|
|
||||||
[ProducesResponseType(typeof(PagedViewModel<ReferenceByIdModel>), StatusCodes.Status200OK)]
|
|
||||||
public async Task<ActionResult<PagedViewModel<ReferenceByIdModel>>> ReferencedDescendants(
|
public async Task<ActionResult<PagedViewModel<ReferenceByIdModel>>> ReferencedDescendants(
|
||||||
CancellationToken cancellationToken,
|
CancellationToken cancellationToken,
|
||||||
Guid id,
|
Guid id,
|
||||||
@@ -47,4 +42,38 @@ public class ReferencedDescendantsMemberController : MemberControllerBase
|
|||||||
|
|
||||||
return pagedViewModel;
|
return pagedViewModel;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a page list of the child nodes of the current item used in any kind of relation.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// Used when deleting and unpublishing a single item to check if this item has any descending items that are in any
|
||||||
|
/// kind of relation.
|
||||||
|
/// This is basically finding the descending items which are children in relations.
|
||||||
|
/// </remarks>
|
||||||
|
[HttpGet("{id:guid}/referenced-descendants")]
|
||||||
|
[MapToApiVersion("1.0")]
|
||||||
|
[ProducesResponseType(typeof(PagedViewModel<ReferenceByIdModel>), StatusCodes.Status200OK)]
|
||||||
|
[ProducesResponseType(typeof(ProblemDetails), StatusCodes.Status404NotFound)]
|
||||||
|
public async Task<IActionResult> ReferencedDescendants2(
|
||||||
|
CancellationToken cancellationToken,
|
||||||
|
Guid id,
|
||||||
|
int skip = 0,
|
||||||
|
int take = 20)
|
||||||
|
{
|
||||||
|
Attempt<PagedModel<RelationItemModel>, GetReferencesOperationStatus> relationItemsAttempt = await _trackedReferencesSkipTakeService.GetPagedDescendantsInReferencesAsync(id, UmbracoObjectTypes.Member, skip, take, true);
|
||||||
|
|
||||||
|
if (relationItemsAttempt.Success is false)
|
||||||
|
{
|
||||||
|
return GetReferencesOperationStatusResult(relationItemsAttempt.Status);
|
||||||
|
}
|
||||||
|
|
||||||
|
var pagedViewModel = new PagedViewModel<ReferenceByIdModel>
|
||||||
|
{
|
||||||
|
Total = relationItemsAttempt.Result.Total,
|
||||||
|
Items = _umbracoMapper.MapEnumerable<RelationItemModel, ReferenceByIdModel>(relationItemsAttempt.Result.Items),
|
||||||
|
};
|
||||||
|
|
||||||
|
return Ok(pagedViewModel);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9628,6 +9628,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ProblemDetails"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"401": {
|
"401": {
|
||||||
"description": "The resource is protected and requires an authentication token"
|
"description": "The resource is protected and requires an authentication token"
|
||||||
},
|
},
|
||||||
@@ -9692,6 +9706,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ProblemDetails"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"401": {
|
"401": {
|
||||||
"description": "The resource is protected and requires an authentication token"
|
"description": "The resource is protected and requires an authentication token"
|
||||||
},
|
},
|
||||||
@@ -17348,6 +17376,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ProblemDetails"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"401": {
|
"401": {
|
||||||
"description": "The resource is protected and requires an authentication token"
|
"description": "The resource is protected and requires an authentication token"
|
||||||
},
|
},
|
||||||
@@ -17412,6 +17454,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ProblemDetails"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"401": {
|
"401": {
|
||||||
"description": "The resource is protected and requires an authentication token"
|
"description": "The resource is protected and requires an authentication token"
|
||||||
},
|
},
|
||||||
@@ -21653,6 +21709,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ProblemDetails"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"401": {
|
"401": {
|
||||||
"description": "The resource is protected and requires an authentication token"
|
"description": "The resource is protected and requires an authentication token"
|
||||||
},
|
},
|
||||||
@@ -21717,6 +21787,20 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
"404": {
|
||||||
|
"description": "Not Found",
|
||||||
|
"content": {
|
||||||
|
"application/json": {
|
||||||
|
"schema": {
|
||||||
|
"oneOf": [
|
||||||
|
{
|
||||||
|
"$ref": "#/components/schemas/ProblemDetails"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
"401": {
|
"401": {
|
||||||
"description": "The resource is protected and requires an authentication token"
|
"description": "The resource is protected and requires an authentication token"
|
||||||
},
|
},
|
||||||
@@ -49575,4 +49659,4 @@
|
|||||||
"name": "Webhook"
|
"name": "Webhook"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
using Umbraco.Cms.Core.Models;
|
using Umbraco.Cms.Core.Models;
|
||||||
|
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||||
|
|
||||||
namespace Umbraco.Cms.Core.Services;
|
namespace Umbraco.Cms.Core.Services;
|
||||||
|
|
||||||
@@ -16,8 +17,27 @@ public interface ITrackedReferencesService
|
|||||||
/// dependencies (isDependency field is set to true).
|
/// dependencies (isDependency field is set to true).
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <returns>A paged result of <see cref="RelationItemModel" /> objects.</returns>
|
/// <returns>A paged result of <see cref="RelationItemModel" /> objects.</returns>
|
||||||
|
[Obsolete("Use GetPagedRelationsForItemAsync which returns an Attempt with operation status. Scheduled for removal in Umbraco 19.")]
|
||||||
Task<PagedModel<RelationItemModel>> GetPagedRelationsForItemAsync(Guid key, long skip, long take, bool filterMustBeIsDependency);
|
Task<PagedModel<RelationItemModel>> GetPagedRelationsForItemAsync(Guid key, long skip, long take, bool filterMustBeIsDependency);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a paged result of items which are in relation with the current item.
|
||||||
|
/// Basically, shows the items which depend on the current item.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="key">The identifier of the entity to retrieve relations for.</param>
|
||||||
|
/// <param name="objectType">The Umbraco object type of the parent.</param>
|
||||||
|
/// <param name="skip">The amount of items to skip</param>
|
||||||
|
/// <param name="take">The amount of items to take.</param>
|
||||||
|
/// <param name="filterMustBeIsDependency">
|
||||||
|
/// A boolean indicating whether to filter only the RelationTypes which are
|
||||||
|
/// dependencies (isDependency field is set to true).
|
||||||
|
/// </param>
|
||||||
|
/// <returns>A paged result of <see cref="RelationItemModel" /> objects.</returns>
|
||||||
|
async Task<Attempt<PagedModel<RelationItemModel>, GetReferencesOperationStatus>> GetPagedRelationsForItemAsync(Guid key, UmbracoObjectTypes objectType, long skip, long take, bool filterMustBeIsDependency)
|
||||||
|
#pragma warning disable CS0618 // Type or member is obsolete
|
||||||
|
=> Attempt.SucceedWithStatus(GetReferencesOperationStatus.Success, await GetPagedRelationsForItemAsync(key, skip, take, filterMustBeIsDependency));
|
||||||
|
#pragma warning restore CS0618 // Type or member is obsolete
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a paged result of items which are in relation with an item in the recycle bin.
|
/// Gets a paged result of items which are in relation with an item in the recycle bin.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
@@ -42,8 +62,26 @@ public interface ITrackedReferencesService
|
|||||||
/// dependencies (isDependency field is set to true).
|
/// dependencies (isDependency field is set to true).
|
||||||
/// </param>
|
/// </param>
|
||||||
/// <returns>A paged result of <see cref="RelationItemModel" /> objects.</returns>
|
/// <returns>A paged result of <see cref="RelationItemModel" /> objects.</returns>
|
||||||
|
[Obsolete("Use GetPagedDescendantsInReferencesAsync which returns an Attempt with operation status. Scheduled for removal in Umbraco 19.")]
|
||||||
Task<PagedModel<RelationItemModel>> GetPagedDescendantsInReferencesAsync(Guid parentKey, long skip, long take, bool filterMustBeIsDependency);
|
Task<PagedModel<RelationItemModel>> GetPagedDescendantsInReferencesAsync(Guid parentKey, long skip, long take, bool filterMustBeIsDependency);
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Gets a paged result of the descending items that have any references, given a parent id.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="parentKey">The unique identifier of the parent to retrieve descendants for.</param>
|
||||||
|
/// <param name="objectType">The Umbraco object type of the parent.</param>
|
||||||
|
/// <param name="skip">The amount of items to skip</param>
|
||||||
|
/// <param name="take">The amount of items to take.</param>
|
||||||
|
/// <param name="filterMustBeIsDependency">
|
||||||
|
/// A boolean indicating whether to filter only the RelationTypes which are
|
||||||
|
/// dependencies (isDependency field is set to true).
|
||||||
|
/// </param>
|
||||||
|
/// <returns>An <see cref="Attempt"/> wrapping a paged result of <see cref="RelationItemModel" /> objects.</returns>
|
||||||
|
async Task<Attempt<PagedModel<RelationItemModel>, GetReferencesOperationStatus>> GetPagedDescendantsInReferencesAsync(Guid parentKey, UmbracoObjectTypes objectType, long skip, long take, bool filterMustBeIsDependency)
|
||||||
|
#pragma warning disable CS0618 // Type or member is obsolete
|
||||||
|
=> Attempt.SucceedWithStatus(GetReferencesOperationStatus.Success, await GetPagedDescendantsInReferencesAsync(parentKey, skip, take, filterMustBeIsDependency));
|
||||||
|
#pragma warning restore CS0618 // Type or member is obsolete
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Gets a paged result of items used in any kind of relation from selected integer ids.
|
/// Gets a paged result of items used in any kind of relation from selected integer ids.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
|||||||
@@ -0,0 +1,7 @@
|
|||||||
|
namespace Umbraco.Cms.Core.Services.OperationStatus;
|
||||||
|
|
||||||
|
public enum GetReferencesOperationStatus
|
||||||
|
{
|
||||||
|
Success,
|
||||||
|
ContentNotFound
|
||||||
|
}
|
||||||
@@ -1,6 +1,8 @@
|
|||||||
using Umbraco.Cms.Core.Models;
|
using Umbraco.Cms.Core.Models;
|
||||||
|
using Umbraco.Cms.Core.Models.Entities;
|
||||||
using Umbraco.Cms.Core.Persistence.Repositories;
|
using Umbraco.Cms.Core.Persistence.Repositories;
|
||||||
using Umbraco.Cms.Core.Scoping;
|
using Umbraco.Cms.Core.Scoping;
|
||||||
|
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||||
|
|
||||||
namespace Umbraco.Cms.Core.Services;
|
namespace Umbraco.Cms.Core.Services;
|
||||||
|
|
||||||
@@ -20,6 +22,7 @@ public class TrackedReferencesService : ITrackedReferencesService
|
|||||||
_entityService = entityService;
|
_entityService = entityService;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete("Use the GetPagedRelationsForItemAsync overload which returns an Attempt with operation status. Scheduled for removal in Umbraco 19.")]
|
||||||
public Task<PagedModel<RelationItemModel>> GetPagedRelationsForItemAsync(Guid key, long skip, long take, bool filterMustBeIsDependency)
|
public Task<PagedModel<RelationItemModel>> GetPagedRelationsForItemAsync(Guid key, long skip, long take, bool filterMustBeIsDependency)
|
||||||
{
|
{
|
||||||
using ICoreScope scope = _scopeProvider.CreateCoreScope(autoComplete: true);
|
using ICoreScope scope = _scopeProvider.CreateCoreScope(autoComplete: true);
|
||||||
@@ -29,6 +32,21 @@ public class TrackedReferencesService : ITrackedReferencesService
|
|||||||
return Task.FromResult(pagedModel);
|
return Task.FromResult(pagedModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<Attempt<PagedModel<RelationItemModel>, GetReferencesOperationStatus>> GetPagedRelationsForItemAsync(Guid key, UmbracoObjectTypes objectType, long skip, long take, bool filterMustBeIsDependency)
|
||||||
|
{
|
||||||
|
IEntitySlim? entity = _entityService.Get(key, objectType);
|
||||||
|
if (entity is null)
|
||||||
|
{
|
||||||
|
return Attempt.FailWithStatus(GetReferencesOperationStatus.ContentNotFound, new PagedModel<RelationItemModel>());
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CS0618 // Type or member is obsolete (but using whilst it exists to avoid code repetition)
|
||||||
|
PagedModel<RelationItemModel> pagedModel = await GetPagedRelationsForItemAsync(key, skip, take, filterMustBeIsDependency);
|
||||||
|
#pragma warning restore CS0618 // Type or member is obsolete
|
||||||
|
|
||||||
|
return Attempt.SucceedWithStatus(GetReferencesOperationStatus.Success, pagedModel);
|
||||||
|
}
|
||||||
|
|
||||||
public Task<PagedModel<RelationItemModel>> GetPagedRelationsForRecycleBinAsync(UmbracoObjectTypes objectType, long skip, long take, bool filterMustBeIsDependency)
|
public Task<PagedModel<RelationItemModel>> GetPagedRelationsForRecycleBinAsync(UmbracoObjectTypes objectType, long skip, long take, bool filterMustBeIsDependency)
|
||||||
{
|
{
|
||||||
Guid objectTypeKey = objectType switch
|
Guid objectTypeKey = objectType switch
|
||||||
@@ -44,6 +62,7 @@ public class TrackedReferencesService : ITrackedReferencesService
|
|||||||
return Task.FromResult(pagedModel);
|
return Task.FromResult(pagedModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Obsolete("Use GetPagedDescendantsInReferencesAsync which returns an Attempt with operation status. Scheduled for removal in Umbraco 19.")]
|
||||||
public Task<PagedModel<RelationItemModel>> GetPagedDescendantsInReferencesAsync(Guid parentKey, long skip, long take, bool filterMustBeIsDependency)
|
public Task<PagedModel<RelationItemModel>> GetPagedDescendantsInReferencesAsync(Guid parentKey, long skip, long take, bool filterMustBeIsDependency)
|
||||||
{
|
{
|
||||||
using ICoreScope scope = _scopeProvider.CreateCoreScope(autoComplete: true);
|
using ICoreScope scope = _scopeProvider.CreateCoreScope(autoComplete: true);
|
||||||
@@ -59,6 +78,21 @@ public class TrackedReferencesService : ITrackedReferencesService
|
|||||||
return Task.FromResult(pagedModel);
|
return Task.FromResult(pagedModel);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public async Task<Attempt<PagedModel<RelationItemModel>, GetReferencesOperationStatus>> GetPagedDescendantsInReferencesAsync(Guid parentKey, UmbracoObjectTypes objectType, long skip, long take, bool filterMustBeIsDependency)
|
||||||
|
{
|
||||||
|
IEntitySlim? entity = _entityService.Get(parentKey, objectType);
|
||||||
|
if (entity is null)
|
||||||
|
{
|
||||||
|
return Attempt.FailWithStatus(GetReferencesOperationStatus.ContentNotFound, new PagedModel<RelationItemModel>());
|
||||||
|
}
|
||||||
|
|
||||||
|
#pragma warning disable CS0618 // Type or member is obsolete (but using whilst it exists to avoid code repetition)
|
||||||
|
PagedModel<RelationItemModel> pagedModel = await GetPagedDescendantsInReferencesAsync(parentKey, skip, take, filterMustBeIsDependency);
|
||||||
|
#pragma warning restore CS0618 // Type or member is obsolete
|
||||||
|
|
||||||
|
return Attempt.SucceedWithStatus(GetReferencesOperationStatus.Success, pagedModel);
|
||||||
|
}
|
||||||
|
|
||||||
public Task<PagedModel<RelationItemModel>> GetPagedItemsWithRelationsAsync(ISet<Guid> keys, long skip, long take, bool filterMustBeIsDependency)
|
public Task<PagedModel<RelationItemModel>> GetPagedItemsWithRelationsAsync(ISet<Guid> keys, long skip, long take, bool filterMustBeIsDependency)
|
||||||
{
|
{
|
||||||
using ICoreScope scope = _scopeProvider.CreateCoreScope(autoComplete: true);
|
using ICoreScope scope = _scopeProvider.CreateCoreScope(autoComplete: true);
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ using Umbraco.Cms.Core;
|
|||||||
using Umbraco.Cms.Core.Models;
|
using Umbraco.Cms.Core.Models;
|
||||||
using Umbraco.Cms.Core.Notifications;
|
using Umbraco.Cms.Core.Notifications;
|
||||||
using Umbraco.Cms.Core.Services;
|
using Umbraco.Cms.Core.Services;
|
||||||
|
using Umbraco.Cms.Core.Services.OperationStatus;
|
||||||
using Umbraco.Cms.Infrastructure.Persistence.Relations;
|
using Umbraco.Cms.Infrastructure.Persistence.Relations;
|
||||||
using Umbraco.Cms.Tests.Common.Builders;
|
using Umbraco.Cms.Tests.Common.Builders;
|
||||||
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
using Umbraco.Cms.Tests.Common.Builders.Extensions;
|
||||||
@@ -77,25 +78,55 @@ internal class TrackedReferencesServiceTests : UmbracoIntegrationTest
|
|||||||
{
|
{
|
||||||
var sut = GetRequiredService<ITrackedReferencesService>();
|
var sut = GetRequiredService<ITrackedReferencesService>();
|
||||||
|
|
||||||
var actual = await sut.GetPagedRelationsForItemAsync(Root1.Key, 0, 10, true);
|
var actual = await sut.GetPagedRelationsForItemAsync(Root1.Key, UmbracoObjectTypes.Document, 0, 10, true);
|
||||||
|
|
||||||
Assert.Multiple(() =>
|
Assert.Multiple(() =>
|
||||||
{
|
{
|
||||||
Assert.AreEqual(1, actual.Total);
|
Assert.IsTrue(actual.Success);
|
||||||
var item = actual.Items.FirstOrDefault();
|
Assert.AreEqual(1, actual.Result.Total);
|
||||||
|
var item = actual.Result.Items.FirstOrDefault();
|
||||||
Assert.AreEqual(Root2.ContentType.Alias, item?.ContentTypeAlias);
|
Assert.AreEqual(Root2.ContentType.Alias, item?.ContentTypeAlias);
|
||||||
Assert.AreEqual(Root2.Key, item?.NodeKey);
|
Assert.AreEqual(Root2.Key, item?.NodeKey);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Get_Relations_For_Non_Existing_Page_Returns_Not_Found()
|
||||||
|
{
|
||||||
|
var sut = GetRequiredService<ITrackedReferencesService>();
|
||||||
|
|
||||||
|
var actual = await sut.GetPagedRelationsForItemAsync(Guid.NewGuid(), UmbracoObjectTypes.Document, 0, 10, true);
|
||||||
|
|
||||||
|
Assert.Multiple(() =>
|
||||||
|
{
|
||||||
|
Assert.IsFalse(actual.Success);
|
||||||
|
Assert.AreEqual(GetReferencesOperationStatus.ContentNotFound, actual.Status);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public async Task Get_Descendants_In_References_For_Non_Existing_Page_Returns_Not_Found()
|
||||||
|
{
|
||||||
|
var sut = GetRequiredService<ITrackedReferencesService>();
|
||||||
|
|
||||||
|
var actual = await sut.GetPagedDescendantsInReferencesAsync(Guid.NewGuid(), UmbracoObjectTypes.Document, 0, 10, true);
|
||||||
|
|
||||||
|
Assert.Multiple(() =>
|
||||||
|
{
|
||||||
|
Assert.IsFalse(actual.Success);
|
||||||
|
Assert.AreEqual(GetReferencesOperationStatus.ContentNotFound, actual.Status);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public async Task Does_Not_Return_References_If_Item_Is_Not_Referenced()
|
public async Task Does_Not_Return_References_If_Item_Is_Not_Referenced()
|
||||||
{
|
{
|
||||||
var sut = GetRequiredService<ITrackedReferencesService>();
|
var sut = GetRequiredService<ITrackedReferencesService>();
|
||||||
|
|
||||||
var actual = await sut.GetPagedRelationsForItemAsync(Root2.Key, 0, 10, true);
|
var actual = await sut.GetPagedRelationsForItemAsync(Root2.Key, UmbracoObjectTypes.Document, 0, 10, true);
|
||||||
|
|
||||||
Assert.AreEqual(0, actual.Total);
|
Assert.IsTrue(actual.Success);
|
||||||
|
Assert.AreEqual(0, actual.Result.Total);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
|||||||
Reference in New Issue
Block a user