Skip to content

Commit 515b039

Browse files
Merge branch 'contrib' into pr/18893
2 parents 347595c + e7a52de commit 515b039

File tree

487 files changed

+10354
-4420
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

487 files changed

+10354
-4420
lines changed

.vscode/lit.code-snippets

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
../src/Umbraco.Web.UI.Client/.vscode/lit.code-snippets

.vscode/settings.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"cSpell.words": [
3+
"unprovide"
4+
]
5+
}

src/Umbraco.Cms.Api.Management/Controllers/Document/References/AreReferencedDocumentController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Asp.Versioning;
1+
using Asp.Versioning;
22
using Microsoft.AspNetCore.Http;
33
using Microsoft.AspNetCore.Mvc;
44
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
@@ -45,6 +45,6 @@ public async Task<ActionResult<PagedViewModel<ReferenceByIdModel>>> GetPagedRefe
4545
Items = _umbracoMapper.MapEnumerable<Guid, ReferenceByIdModel>(distinctByKeyItemsWithReferencedRelations.Items),
4646
};
4747

48-
return await Task.FromResult(pagedViewModel);
48+
return pagedViewModel;
4949
}
5050
}

src/Umbraco.Cms.Api.Management/Controllers/Document/References/ReferencedByDocumentController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,6 @@ public async Task<ActionResult<PagedViewModel<IReferenceResponseModel>>> Referen
4545
Items = await _relationTypePresentationFactory.CreateReferenceResponseModelsAsync(relationItems.Items),
4646
};
4747

48-
return await Task.FromResult(pagedViewModel);
48+
return pagedViewModel;
4949
}
5050
}

src/Umbraco.Cms.Api.Management/Controllers/Document/References/ReferencedDescendantsDocumentController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Asp.Versioning;
1+
using Asp.Versioning;
22
using Microsoft.AspNetCore.Http;
33
using Microsoft.AspNetCore.Mvc;
44
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
@@ -45,6 +45,6 @@ public async Task<ActionResult<PagedViewModel<ReferenceByIdModel>>> ReferencedDe
4545
Items = _umbracoMapper.MapEnumerable<RelationItemModel, ReferenceByIdModel>(relationItems.Items),
4646
};
4747

48-
return await Task.FromResult(pagedViewModel);
48+
return pagedViewModel;
4949
}
5050
}

src/Umbraco.Cms.Api.Management/Controllers/Media/References/AreReferencedMediaController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Asp.Versioning;
1+
using Asp.Versioning;
22
using Microsoft.AspNetCore.Http;
33
using Microsoft.AspNetCore.Mvc;
44
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
@@ -46,6 +46,6 @@ public async Task<ActionResult<PagedViewModel<ReferenceByIdModel>>> GetPagedRefe
4646
Items = _umbracoMapper.MapEnumerable<Guid, ReferenceByIdModel>(distinctByKeyItemsWithReferencedRelations.Items),
4747
};
4848

49-
return await Task.FromResult(pagedViewModel);
49+
return pagedViewModel;
5050
}
5151
}

src/Umbraco.Cms.Api.Management/Controllers/Media/References/ReferencedByMediaController.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,6 @@ public async Task<ActionResult<PagedViewModel<IReferenceResponseModel>>> Referen
4545
Items = await _relationTypePresentationFactory.CreateReferenceResponseModelsAsync(relationItems.Items),
4646
};
4747

48-
return await Task.FromResult(pagedViewModel);
48+
return pagedViewModel;
4949
}
5050
}

src/Umbraco.Cms.Api.Management/Controllers/Media/References/ReferencedDescendantsMediaController.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Asp.Versioning;
1+
using Asp.Versioning;
22
using Microsoft.AspNetCore.Http;
33
using Microsoft.AspNetCore.Mvc;
44
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
@@ -45,6 +45,6 @@ public async Task<ActionResult<PagedViewModel<ReferenceByIdModel>>> ReferencedDe
4545
Items = _umbracoMapper.MapEnumerable<RelationItemModel, ReferenceByIdModel>(relationItems.Items),
4646
};
4747

48-
return await Task.FromResult(pagedViewModel);
48+
return pagedViewModel;
4949
}
5050
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
using Asp.Versioning;
2+
using Microsoft.AspNetCore.Http;
3+
using Microsoft.AspNetCore.Mvc;
4+
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
5+
using Umbraco.Cms.Api.Management.ViewModels;
6+
using Umbraco.Cms.Core;
7+
using Umbraco.Cms.Core.Mapping;
8+
using Umbraco.Cms.Core.Models;
9+
using Umbraco.Cms.Core.Services;
10+
11+
namespace Umbraco.Cms.Api.Management.Controllers.Member.References;
12+
13+
[ApiVersion("1.0")]
14+
public class AreReferencedMemberController : MemberControllerBase
15+
{
16+
private readonly ITrackedReferencesService _trackedReferencesSkipTakeService;
17+
private readonly IUmbracoMapper _umbracoMapper;
18+
19+
public AreReferencedMemberController(ITrackedReferencesService trackedReferencesSkipTakeService, IUmbracoMapper umbracoMapper)
20+
{
21+
_trackedReferencesSkipTakeService = trackedReferencesSkipTakeService;
22+
_umbracoMapper = umbracoMapper;
23+
}
24+
25+
/// <summary>
26+
/// Gets a page list of the items used in any kind of relation from selected keys.
27+
/// </summary>
28+
/// <remarks>
29+
/// Used when bulk deleting content/media and bulk unpublishing content (delete and unpublish on List view).
30+
/// This is basically finding children of relations.
31+
/// </remarks>
32+
// [HttpGet("item")]
33+
[HttpGet("are-referenced")]
34+
[MapToApiVersion("1.0")]
35+
[ProducesResponseType(typeof(PagedViewModel<ReferenceByIdModel>), StatusCodes.Status200OK)]
36+
public async Task<ActionResult<PagedViewModel<ReferenceByIdModel>>> GetPagedReferencedItems(
37+
CancellationToken cancellationToken,
38+
[FromQuery(Name="id")] HashSet<Guid> ids,
39+
int skip = 0,
40+
int take = 20)
41+
{
42+
PagedModel<Guid> distinctByKeyItemsWithReferencedRelations = await _trackedReferencesSkipTakeService.GetPagedKeysWithDependentReferencesAsync(ids, Constants.ObjectTypes.Member, skip, take);
43+
var pagedViewModel = new PagedViewModel<ReferenceByIdModel>
44+
{
45+
Total = distinctByKeyItemsWithReferencedRelations.Total,
46+
Items = _umbracoMapper.MapEnumerable<Guid, ReferenceByIdModel>(distinctByKeyItemsWithReferencedRelations.Items),
47+
};
48+
49+
return pagedViewModel;
50+
}
51+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using Asp.Versioning;
2+
using Microsoft.AspNetCore.Http;
3+
using Microsoft.AspNetCore.Mvc;
4+
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
5+
using Umbraco.Cms.Api.Management.Factories;
6+
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
7+
using Umbraco.Cms.Core.Models;
8+
using Umbraco.Cms.Core.Services;
9+
10+
namespace Umbraco.Cms.Api.Management.Controllers.Member.References;
11+
12+
[ApiVersion("1.0")]
13+
public class ReferencedByMemberController : MemberControllerBase
14+
{
15+
private readonly ITrackedReferencesService _trackedReferencesService;
16+
private readonly IRelationTypePresentationFactory _relationTypePresentationFactory;
17+
18+
public ReferencedByMemberController(ITrackedReferencesService trackedReferencesService, IRelationTypePresentationFactory relationTypePresentationFactory)
19+
{
20+
_trackedReferencesService = trackedReferencesService;
21+
_relationTypePresentationFactory = relationTypePresentationFactory;
22+
}
23+
24+
/// <summary>
25+
/// Gets a page list of tracked references for the current item, so you can see where an item is being used.
26+
/// </summary>
27+
/// <remarks>
28+
/// Used by info tabs on content, media etc. and for the delete and unpublish of single items.
29+
/// This is basically finding parents of relations.
30+
/// </remarks>
31+
[HttpGet("{id:guid}/referenced-by")]
32+
[MapToApiVersion("1.0")]
33+
[ProducesResponseType(typeof(PagedViewModel<IReferenceResponseModel>), StatusCodes.Status200OK)]
34+
public async Task<ActionResult<PagedViewModel<IReferenceResponseModel>>> ReferencedBy(
35+
CancellationToken cancellationToken,
36+
Guid id,
37+
int skip = 0,
38+
int take = 20)
39+
{
40+
PagedModel<RelationItemModel> relationItems = await _trackedReferencesService.GetPagedRelationsForItemAsync(id, skip, take, true);
41+
42+
var pagedViewModel = new PagedViewModel<IReferenceResponseModel>
43+
{
44+
Total = relationItems.Total,
45+
Items = await _relationTypePresentationFactory.CreateReferenceResponseModelsAsync(relationItems.Items),
46+
};
47+
48+
return pagedViewModel;
49+
}
50+
}
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
using Asp.Versioning;
2+
using Microsoft.AspNetCore.Http;
3+
using Microsoft.AspNetCore.Mvc;
4+
using Umbraco.Cms.Api.Common.ViewModels.Pagination;
5+
using Umbraco.Cms.Api.Management.ViewModels;
6+
using Umbraco.Cms.Core.Mapping;
7+
using Umbraco.Cms.Core.Models;
8+
using Umbraco.Cms.Core.Services;
9+
10+
namespace Umbraco.Cms.Api.Management.Controllers.Member.References;
11+
12+
[ApiVersion("1.0")]
13+
public class ReferencedDescendantsMemberController : MemberControllerBase
14+
{
15+
private readonly ITrackedReferencesService _trackedReferencesSkipTakeService;
16+
private readonly IUmbracoMapper _umbracoMapper;
17+
18+
public ReferencedDescendantsMemberController(ITrackedReferencesService trackedReferencesSkipTakeService, IUmbracoMapper umbracoMapper)
19+
{
20+
_trackedReferencesSkipTakeService = trackedReferencesSkipTakeService;
21+
_umbracoMapper = umbracoMapper;
22+
}
23+
24+
/// <summary>
25+
/// Gets a page list of the child nodes of the current item used in any kind of relation.
26+
/// </summary>
27+
/// <remarks>
28+
/// Used when deleting and unpublishing a single item to check if this item has any descending items that are in any
29+
/// kind of relation.
30+
/// This is basically finding the descending items which are children in relations.
31+
/// </remarks>
32+
[HttpGet("{id:guid}/referenced-descendants")]
33+
[MapToApiVersion("1.0")]
34+
[ProducesResponseType(typeof(PagedViewModel<ReferenceByIdModel>), StatusCodes.Status200OK)]
35+
public async Task<ActionResult<PagedViewModel<ReferenceByIdModel>>> ReferencedDescendants(
36+
CancellationToken cancellationToken,
37+
Guid id,
38+
int skip = 0,
39+
int take = 20)
40+
{
41+
PagedModel<RelationItemModel> relationItems = await _trackedReferencesSkipTakeService.GetPagedDescendantsInReferencesAsync(id, skip, take, true);
42+
var pagedViewModel = new PagedViewModel<ReferenceByIdModel>
43+
{
44+
Total = relationItems.Total,
45+
Items = _umbracoMapper.MapEnumerable<RelationItemModel, ReferenceByIdModel>(relationItems.Items),
46+
};
47+
48+
return pagedViewModel;
49+
}
50+
}
Lines changed: 62 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,83 @@
1-
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
1+
using Microsoft.Extensions.DependencyInjection;
2+
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
23
using Umbraco.Cms.Core;
4+
using Umbraco.Cms.Core.DependencyInjection;
35
using Umbraco.Cms.Core.Mapping;
46
using Umbraco.Cms.Core.Models;
7+
using Umbraco.Cms.Core.Models.Entities;
8+
using Umbraco.Cms.Core.Persistence.Repositories;
9+
using Umbraco.Cms.Infrastructure.Scoping;
510
using Umbraco.Extensions;
611

712
namespace Umbraco.Cms.Api.Management.Factories;
813

914
public class RelationTypePresentationFactory : IRelationTypePresentationFactory
1015
{
1116
private readonly IUmbracoMapper _umbracoMapper;
17+
private readonly IEntityRepository _entityRepository;
18+
private readonly IDocumentPresentationFactory _documentPresentationFactory;
19+
private readonly IScopeProvider _scopeProvider;
1220

21+
[Obsolete("Please use the non obsoleted constructor. Scheduled for removal in v17")]
1322
public RelationTypePresentationFactory(IUmbracoMapper umbracoMapper)
23+
: this(
24+
umbracoMapper,
25+
StaticServiceProvider.Instance.GetRequiredService<IEntityRepository>(),
26+
StaticServiceProvider.Instance.GetRequiredService<IDocumentPresentationFactory>(),
27+
StaticServiceProvider.Instance.GetRequiredService<IScopeProvider>())
28+
{
29+
}
30+
31+
public RelationTypePresentationFactory(
32+
IUmbracoMapper umbracoMapper,
33+
IEntityRepository entityRepository,
34+
IDocumentPresentationFactory documentPresentationFactory,
35+
IScopeProvider scopeProvider)
1436
{
1537
_umbracoMapper = umbracoMapper;
38+
_entityRepository = entityRepository;
39+
_documentPresentationFactory = documentPresentationFactory;
40+
_scopeProvider = scopeProvider;
1641
}
1742

18-
public async Task<IEnumerable<IReferenceResponseModel>> CreateReferenceResponseModelsAsync(IEnumerable<RelationItemModel> relationItemModels)
43+
public async Task<IEnumerable<IReferenceResponseModel>> CreateReferenceResponseModelsAsync(
44+
IEnumerable<RelationItemModel> relationItemModels)
1945
{
20-
IReferenceResponseModel[] result = relationItemModels.Select(relationItemModel => relationItemModel.NodeType switch
21-
{
22-
Constants.UdiEntityType.Document => _umbracoMapper.Map<DocumentReferenceResponseModel>(relationItemModel),
23-
Constants.UdiEntityType.Media => _umbracoMapper.Map<MediaReferenceResponseModel>(relationItemModel),
24-
_ => _umbracoMapper.Map<DefaultReferenceResponseModel>(relationItemModel) as IReferenceResponseModel,
25-
}).WhereNotNull().ToArray();
46+
IReadOnlyCollection<RelationItemModel> relationItemModelsCollection = relationItemModels.ToArray();
47+
48+
Guid[] documentKeys = relationItemModelsCollection
49+
.Where(item => item.NodeType is Constants.UdiEntityType.Document)
50+
.Select(item => item.NodeKey).Distinct().ToArray();
51+
52+
using IScope scope = _scopeProvider.CreateScope(autoComplete: true);
53+
54+
var slimEntities = _entityRepository.GetAll(Constants.ObjectTypes.Document, documentKeys).ToList();
55+
56+
IReferenceResponseModel[] result = relationItemModelsCollection.Select(relationItemModel =>
57+
relationItemModel.NodeType switch
58+
{
59+
Constants.UdiEntityType.Document => MapDocumentReference(relationItemModel, slimEntities),
60+
Constants.UdiEntityType.Media => _umbracoMapper.Map<MediaReferenceResponseModel>(relationItemModel),
61+
Constants.UdiEntityType.Member => _umbracoMapper.Map<MemberReferenceResponseModel>(relationItemModel),
62+
_ => _umbracoMapper.Map<DefaultReferenceResponseModel>(relationItemModel),
63+
}).WhereNotNull().ToArray();
2664

2765
return await Task.FromResult(result);
2866
}
67+
68+
private IReferenceResponseModel? MapDocumentReference(RelationItemModel relationItemModel,
69+
List<IEntitySlim> slimEntities)
70+
{
71+
DocumentReferenceResponseModel? documentReferenceResponseModel =
72+
_umbracoMapper.Map<DocumentReferenceResponseModel>(relationItemModel);
73+
if (documentReferenceResponseModel is not null
74+
&& slimEntities.FirstOrDefault(e => e.Key == relationItemModel.NodeKey) is DocumentEntitySlim
75+
matchingSlimDocument)
76+
{
77+
documentReferenceResponseModel.Variants =
78+
_documentPresentationFactory.CreateVariantsItemResponseModels(matchingSlimDocument);
79+
}
80+
81+
return documentReferenceResponseModel;
82+
}
2983
}

src/Umbraco.Cms.Api.Management/Mapping/TrackedReferences/TrackedReferenceViewModelsMapDefinition.cs

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
using Umbraco.Cms.Api.Management.ViewModels;
1+
using Umbraco.Cms.Api.Management.ViewModels;
22
using Umbraco.Cms.Core.Mapping;
33
using Umbraco.Cms.Core.Models;
44
using Umbraco.Cms.Api.Management.ViewModels.TrackedReferences;
@@ -11,12 +11,13 @@ public void DefineMaps(IUmbracoMapper mapper)
1111
{
1212
mapper.Define<RelationItemModel, DocumentReferenceResponseModel>((source, context) => new DocumentReferenceResponseModel(), Map);
1313
mapper.Define<RelationItemModel, MediaReferenceResponseModel>((source, context) => new MediaReferenceResponseModel(), Map);
14+
mapper.Define<RelationItemModel, MemberReferenceResponseModel>((source, context) => new MemberReferenceResponseModel(), Map);
1415
mapper.Define<RelationItemModel, DefaultReferenceResponseModel>((source, context) => new DefaultReferenceResponseModel(), Map);
1516
mapper.Define<RelationItemModel, ReferenceByIdModel>((source, context) => new ReferenceByIdModel(), Map);
1617
mapper.Define<Guid, ReferenceByIdModel>((source, context) => new ReferenceByIdModel(), Map);
1718
}
1819

19-
// Umbraco.Code.MapAll
20+
// Umbraco.Code.MapAll -Variants
2021
private void Map(RelationItemModel source, DocumentReferenceResponseModel target, MapperContext context)
2122
{
2223
target.Id = source.NodeKey;
@@ -43,6 +44,19 @@ private void Map(RelationItemModel source, MediaReferenceResponseModel target, M
4344
};
4445
}
4546

47+
// Umbraco.Code.MapAll
48+
private void Map(RelationItemModel source, MemberReferenceResponseModel target, MapperContext context)
49+
{
50+
target.Id = source.NodeKey;
51+
target.Name = source.NodeName;
52+
target.MemberType = new TrackedReferenceMemberType
53+
{
54+
Alias = source.ContentTypeAlias,
55+
Icon = source.ContentTypeIcon,
56+
Name = source.ContentTypeName,
57+
};
58+
}
59+
4660
// Umbraco.Code.MapAll
4761
private void Map(RelationItemModel source, DefaultReferenceResponseModel target, MapperContext context)
4862
{

0 commit comments

Comments
 (0)