Files
Umbraco-CMS/src/Umbraco.Core/Services/TrackedReferencesService.cs
Andy Butland 7d0101170e 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)
2025-12-02 13:28:50 +09:00

111 lines
5.7 KiB
C#

using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.Entities;
using Umbraco.Cms.Core.Persistence.Repositories;
using Umbraco.Cms.Core.Scoping;
using Umbraco.Cms.Core.Services.OperationStatus;
namespace Umbraco.Cms.Core.Services;
public class TrackedReferencesService : ITrackedReferencesService
{
private readonly ICoreScopeProvider _scopeProvider;
private readonly IEntityService _entityService;
private readonly ITrackedReferencesRepository _trackedReferencesRepository;
public TrackedReferencesService(
ITrackedReferencesRepository trackedReferencesRepository,
ICoreScopeProvider scopeProvider,
IEntityService entityService)
{
_trackedReferencesRepository = trackedReferencesRepository;
_scopeProvider = scopeProvider;
_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)
{
using ICoreScope scope = _scopeProvider.CreateCoreScope(autoComplete: true);
IEnumerable<RelationItemModel> items = _trackedReferencesRepository.GetPagedRelationsForItem(key, skip, take, filterMustBeIsDependency, out var totalItems);
var pagedModel = new PagedModel<RelationItemModel>(totalItems, items);
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)
{
Guid objectTypeKey = objectType switch
{
UmbracoObjectTypes.Document => Constants.ObjectTypes.Document,
UmbracoObjectTypes.Media => Constants.ObjectTypes.Media,
_ => throw new ArgumentOutOfRangeException(nameof(objectType), "Only documents and media have recycle bin support."),
};
using ICoreScope scope = _scopeProvider.CreateCoreScope(autoComplete: true);
IEnumerable<RelationItemModel> items = _trackedReferencesRepository.GetPagedRelationsForRecycleBin(objectTypeKey, skip, take, filterMustBeIsDependency, out var totalItems);
var pagedModel = new PagedModel<RelationItemModel>(totalItems, items);
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)
{
using ICoreScope scope = _scopeProvider.CreateCoreScope(autoComplete: true);
IEnumerable<RelationItemModel> items = _trackedReferencesRepository.GetPagedDescendantsInReferences(
parentKey,
skip,
take,
filterMustBeIsDependency,
out var totalItems);
var pagedModel = new PagedModel<RelationItemModel>(totalItems, items);
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)
{
using ICoreScope scope = _scopeProvider.CreateCoreScope(autoComplete: true);
IEnumerable<RelationItemModel> items = _trackedReferencesRepository.GetPagedItemsWithRelations(keys, skip, take, filterMustBeIsDependency, out var totalItems);
var pagedModel = new PagedModel<RelationItemModel>(totalItems, items);
return Task.FromResult(pagedModel);
}
public async Task<PagedModel<Guid>> GetPagedKeysWithDependentReferencesAsync(ISet<Guid> keys, Guid objectTypeId, long skip, long take)
{
using ICoreScope scope = _scopeProvider.CreateCoreScope(autoComplete: true);
return await _trackedReferencesRepository.GetPagedNodeKeysWithDependantReferencesAsync(keys, objectTypeId, skip, take);
}
}