From 8d9f3d0d2a7d03a6975856258d9dd6340e7ba1e4 Mon Sep 17 00:00:00 2001 From: Sven Geusens Date: Tue, 11 Mar 2025 15:11:51 +0100 Subject: [PATCH 1/3] Made variant info available on DocumentReferenceResponseModel --- .../RelationTypePresentationFactory.cs | 60 ++++++++++++++++--- ...TrackedReferenceViewModelsMapDefinition.cs | 2 +- src/Umbraco.Cms.Api.Management/OpenApi.json | 15 ++++- .../DocumentReferenceResponseModel.cs | 6 +- 4 files changed, 71 insertions(+), 12 deletions(-) diff --git a/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs b/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs index 3ce445a12506..e25dd1e6ea18 100644 --- a/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs +++ b/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs @@ -1,7 +1,11 @@ -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.Extensions; namespace Umbraco.Cms.Api.Management.Factories; @@ -9,21 +13,61 @@ namespace Umbraco.Cms.Api.Management.Factories; public class RelationTypePresentationFactory : IRelationTypePresentationFactory { private readonly IUmbracoMapper _umbracoMapper; + private readonly IEntityRepository _entityRepository; + private readonly IDocumentPresentationFactory _documentPresentationFactory; + [Obsolete("Please use the non obsoleted constructor. Scheduled for removal in v17")] public RelationTypePresentationFactory(IUmbracoMapper umbracoMapper) + : this( + umbracoMapper, + StaticServiceProvider.Instance.GetRequiredService(), + StaticServiceProvider.Instance.GetRequiredService()) + { + } + + public RelationTypePresentationFactory( + IUmbracoMapper umbracoMapper, + IEntityRepository entityRepository, + IDocumentPresentationFactory documentPresentationFactory) { _umbracoMapper = umbracoMapper; + _entityRepository = entityRepository; + _documentPresentationFactory = documentPresentationFactory; } - public async Task> CreateReferenceResponseModelsAsync(IEnumerable relationItemModels) + public async Task> CreateReferenceResponseModelsAsync( + IEnumerable relationItemModels) { - 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(); + Guid[] documentKeys = relationItemModels + .Where(item => item.NodeType is Constants.UdiEntityType.Document) + .Select(item => item.NodeKey).Distinct().ToArray(); + + var slimEntities = _entityRepository.GetAll(Constants.ObjectTypes.Document, documentKeys).ToList(); + + IReferenceResponseModel[] result = relationItemModels.Select(relationItemModel => + relationItemModel.NodeType switch + { + Constants.UdiEntityType.Document => MapDocumentReference(relationItemModel, slimEntities), + Constants.UdiEntityType.Media => _umbracoMapper.Map(relationItemModel), + _ => _umbracoMapper.Map(relationItemModel) as IReferenceResponseModel, + }).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 6a4fe40c6203..7a3874271ccb 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 void DefineMaps(IUmbracoMapper mapper) 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 2b365b00b0f5..1ba6c525f202 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, @@ -46514,4 +46525,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 77e1df1d7f4c..e2bb767f992e 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(); } From 3e6b765fa86dc91b88a44cbbdc3b939f4088751a Mon Sep 17 00:00:00 2001 From: Sven Geusens Date: Tue, 18 Mar 2025 10:16:06 +0100 Subject: [PATCH 2/3] Fix scope issue --- .../Factories/RelationTypePresentationFactory.cs | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs b/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs index e25dd1e6ea18..55c06314a52c 100644 --- a/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs +++ b/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs @@ -6,6 +6,7 @@ using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.Entities; using Umbraco.Cms.Core.Persistence.Repositories; +using Umbraco.Cms.Core.Scoping; using Umbraco.Extensions; namespace Umbraco.Cms.Api.Management.Factories; @@ -15,24 +16,28 @@ 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(), + StaticServiceProvider.Instance.GetRequiredService()) { } public RelationTypePresentationFactory( IUmbracoMapper umbracoMapper, IEntityRepository entityRepository, - IDocumentPresentationFactory documentPresentationFactory) + IDocumentPresentationFactory documentPresentationFactory, + IScopeProvider scopeProvider) { _umbracoMapper = umbracoMapper; _entityRepository = entityRepository; _documentPresentationFactory = documentPresentationFactory; + _scopeProvider = scopeProvider; } public async Task> CreateReferenceResponseModelsAsync( @@ -42,6 +47,8 @@ public async Task> CreateReferenceResponseM .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 = relationItemModels.Select(relationItemModel => From 0086eee201f078ed881215e1bddebacf1ac85bde Mon Sep 17 00:00:00 2001 From: Sven Geusens Date: Fri, 21 Mar 2025 13:59:56 +0100 Subject: [PATCH 3/3] PR Feedback + correct scoping --- .../Factories/RelationTypePresentationFactory.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs b/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs index 55c06314a52c..0c718bf66395 100644 --- a/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs +++ b/src/Umbraco.Cms.Api.Management/Factories/RelationTypePresentationFactory.cs @@ -6,7 +6,7 @@ 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.Infrastructure.Scoping; using Umbraco.Extensions; namespace Umbraco.Cms.Api.Management.Factories; @@ -43,7 +43,9 @@ public RelationTypePresentationFactory( public async Task> CreateReferenceResponseModelsAsync( IEnumerable relationItemModels) { - Guid[] documentKeys = relationItemModels + IReadOnlyCollection relationItemModelsCollection = relationItemModels.ToArray(); + + Guid[] documentKeys = relationItemModelsCollection .Where(item => item.NodeType is Constants.UdiEntityType.Document) .Select(item => item.NodeKey).Distinct().ToArray(); @@ -51,12 +53,12 @@ public async Task> CreateReferenceResponseM var slimEntities = _entityRepository.GetAll(Constants.ObjectTypes.Document, documentKeys).ToList(); - IReferenceResponseModel[] result = relationItemModels.Select(relationItemModel => + IReferenceResponseModel[] result = relationItemModelsCollection.Select(relationItemModel => relationItemModel.NodeType switch { Constants.UdiEntityType.Document => MapDocumentReference(relationItemModel, slimEntities), Constants.UdiEntityType.Media => _umbracoMapper.Map(relationItemModel), - _ => _umbracoMapper.Map(relationItemModel) as IReferenceResponseModel, + _ => _umbracoMapper.Map(relationItemModel), }).WhereNotNull().ToArray(); return await Task.FromResult(result);