From 39cad5b2ea74daac6fb37a2e097e731f383af54f Mon Sep 17 00:00:00 2001 From: Sven Geusens Date: Mon, 24 Mar 2025 12:10:30 +0100 Subject: [PATCH] Add variancy information to reference response model (#18645) * Made variant info available on DocumentReferenceResponseModel * Fix scope issue * PR Feedback + correct scoping --- .../RelationTypePresentationFactory.cs | 71 ++++++++++++++++--- ...TrackedReferenceViewModelsMapDefinition.cs | 2 +- src/Umbraco.Cms.Api.Management/OpenApi.json | 15 +++- .../DocumentReferenceResponseModel.cs | 6 +- 4 files changed, 81 insertions(+), 13 deletions(-) diff --git a/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs b/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs index 3ce445a125..0c718bf663 100644 --- a/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs +++ b/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs @@ -1,7 +1,12 @@ -using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences; +using Microsoft.Extensions.DependencyInjection; +using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences; using Umbraco.Cms.Core; +using Umbraco.Cms.Core.DependencyInjection; using Umbraco.Cms.Core.Mapping; using Umbraco.Cms.Core.Models; +using Umbraco.Cms.Core.Models.Entities; +using Umbraco.Cms.Core.Persistence.Repositories; +using Umbraco.Cms.Infrastructure.Scoping; using Umbraco.Extensions; namespace Umbraco.Cms.Api.Management.Factories; @@ -9,21 +14,69 @@ namespace Umbraco.Cms.Api.Management.Factories; public class RelationTypePresentationFactory : IRelationTypePresentationFactory { private readonly IUmbracoMapper _umbracoMapper; + private readonly IEntityRepository _entityRepository; + private readonly IDocumentPresentationFactory _documentPresentationFactory; + private readonly IScopeProvider _scopeProvider; + [Obsolete("Please use the non obsoleted constructor. Scheduled for removal in v17")] public RelationTypePresentationFactory(IUmbracoMapper umbracoMapper) + : this( + umbracoMapper, + StaticServiceProvider.Instance.GetRequiredService(), + StaticServiceProvider.Instance.GetRequiredService(), + StaticServiceProvider.Instance.GetRequiredService()) { - _umbracoMapper = umbracoMapper; } - public async Task> CreateReferenceResponseModelsAsync(IEnumerable relationItemModels) + public RelationTypePresentationFactory( + IUmbracoMapper umbracoMapper, + IEntityRepository entityRepository, + IDocumentPresentationFactory documentPresentationFactory, + IScopeProvider scopeProvider) { - IReferenceResponseModel[] result = relationItemModels.Select(relationItemModel => relationItemModel.NodeType switch - { - Constants.UdiEntityType.Document => _umbracoMapper.Map(relationItemModel), - Constants.UdiEntityType.Media => _umbracoMapper.Map(relationItemModel), - _ => _umbracoMapper.Map(relationItemModel) as IReferenceResponseModel, - }).WhereNotNull().ToArray(); + _umbracoMapper = umbracoMapper; + _entityRepository = entityRepository; + _documentPresentationFactory = documentPresentationFactory; + _scopeProvider = scopeProvider; + } + + public async Task> CreateReferenceResponseModelsAsync( + IEnumerable relationItemModels) + { + IReadOnlyCollection relationItemModelsCollection = relationItemModels.ToArray(); + + Guid[] documentKeys = relationItemModelsCollection + .Where(item => item.NodeType is Constants.UdiEntityType.Document) + .Select(item => item.NodeKey).Distinct().ToArray(); + + using IScope scope = _scopeProvider.CreateScope(autoComplete: true); + + var slimEntities = _entityRepository.GetAll(Constants.ObjectTypes.Document, documentKeys).ToList(); + + IReferenceResponseModel[] result = relationItemModelsCollection.Select(relationItemModel => + relationItemModel.NodeType switch + { + Constants.UdiEntityType.Document => MapDocumentReference(relationItemModel, slimEntities), + Constants.UdiEntityType.Media => _umbracoMapper.Map(relationItemModel), + _ => _umbracoMapper.Map(relationItemModel), + }).WhereNotNull().ToArray(); return await Task.FromResult(result); } + + private IReferenceResponseModel? MapDocumentReference(RelationItemModel relationItemModel, + List slimEntities) + { + DocumentReferenceResponseModel? documentReferenceResponseModel = + _umbracoMapper.Map(relationItemModel); + if (documentReferenceResponseModel is not null + && slimEntities.FirstOrDefault(e => e.Key == relationItemModel.NodeKey) is DocumentEntitySlim + matchingSlimDocument) + { + documentReferenceResponseModel.Variants = + _documentPresentationFactory.CreateVariantsItemResponseModels(matchingSlimDocument); + } + + return documentReferenceResponseModel; + } } diff --git a/src/Umbraco.Cms.Api.Management/Mapping/TrackedReferences/TrackedReferenceViewModelsMapDefinition.cs b/src/Umbraco.Cms.Api.Management/Mapping/TrackedReferences/TrackedReferenceViewModelsMapDefinition.cs index 6a4fe40c62..7a3874271c 100644 --- a/src/Umbraco.Cms.Api.Management/Mapping/TrackedReferences/TrackedReferenceViewModelsMapDefinition.cs +++ b/src/Umbraco.Cms.Api.Management/Mapping/TrackedReferences/TrackedReferenceViewModelsMapDefinition.cs @@ -16,7 +16,7 @@ public class TrackedReferenceViewModelsMapDefinition : IMapDefinition mapper.Define((source, context) => new ReferenceByIdModel(), Map); } - // Umbraco.Code.MapAll + // Umbraco.Code.MapAll -Variants private void Map(RelationItemModel source, DocumentReferenceResponseModel target, MapperContext context) { target.Id = source.NodeKey; diff --git a/src/Umbraco.Cms.Api.Management/OpenApi.json b/src/Umbraco.Cms.Api.Management/OpenApi.json index fd63df8194..ebecf3e9cb 100644 --- a/src/Umbraco.Cms.Api.Management/OpenApi.json +++ b/src/Umbraco.Cms.Api.Management/OpenApi.json @@ -37126,7 +37126,8 @@ "required": [ "$type", "documentType", - "id" + "id", + "variants" ], "type": "object", "properties": { @@ -37151,6 +37152,16 @@ "$ref": "#/components/schemas/TrackedReferenceDocumentTypeModel" } ] + }, + "variants": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/DocumentVariantItemResponseModel" + } + ] + } } }, "additionalProperties": false, @@ -46510,4 +46521,4 @@ } } } -} +} \ No newline at end of file diff --git a/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/DocumentReferenceResponseModel.cs b/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/DocumentReferenceResponseModel.cs index 77e1df1d7f..e2bb767f99 100644 --- a/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/DocumentReferenceResponseModel.cs +++ b/src/Umbraco.Cms.Api.Management/ViewModels/TrackedReferences/DocumentReferenceResponseModel.cs @@ -1,4 +1,6 @@ -namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences; +using Umbraco.Cms.Api.Management.ViewModels.Document; + +namespace Umbraco.Cms.Api.Management.ViewModels.TrackedReferences; public class DocumentReferenceResponseModel : IReferenceResponseModel { @@ -9,4 +11,6 @@ public class DocumentReferenceResponseModel : IReferenceResponseModel public bool? Published { get; set; } public TrackedReferenceDocumentType DocumentType { get; set; } = new(); + + public IEnumerable Variants { get; set; } = Enumerable.Empty(); }